HDLRuby 2.0.9 → 2.0.13

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c831088cf1832ee23b1c6df7132e4845fbba02ad
4
- data.tar.gz: ed0625c1a11fd05da6d7823b6a2ac6d0c09649b0
3
+ metadata.gz: cc8bc67a8b7e6b271c16b81e2b8908b67ba6f3d5
4
+ data.tar.gz: 067d9c0d93e492c267cd85bb4628d52f064b1844
5
5
  SHA512:
6
- metadata.gz: d5597284df1f7e4947ff1c60baaddd6b7d95764c2f5084db0a36a606c0536ada46af0148c747491578adbc53138f17f8f6b42b523bc60e3a5ba7ead914c138cb
7
- data.tar.gz: 812a6fe3e72c8218d00ef7b790e335dea4cc1e1fed7aa655b0cd251fe4c8ace846fbfa70b27436a52b11f258290e1655e88ab5157f0ecfac90104dbe5313b6fa
6
+ metadata.gz: e8ee4d0e62a0693593fe7a5e703e9e5f0c4f50e1bc8795f02c50b7ef59d3f292331aef3d40a959e6c85cd25930bed7ae831c47f713263932af91a7a429ffe67b
7
+ data.tar.gz: 4ef5a298983fc31231fcc4c4b534edc163a023028fd491bc4c6e483bacbb34c223539e9824bc51f5abd8bb1b02216bb32a3ad620f6788bc2e29e6c94198370bc
@@ -14,18 +14,14 @@ Gem::Specification.new do |spec|
14
14
  spec.homepage = "https://github.com/civol"
15
15
  spec.license = "MIT"
16
16
 
17
- # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
- # to allow pushing to a single host or delete this section to allow pushing to any host.
19
- # if spec.respond_to?(:metadata)
20
- # spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
21
- # else
22
- # raise "RubyGems 2.0 or newer is required to protect against " \
23
- # "public gem pushes."
24
- # end
17
+ if spec.respond_to?(:metadata) then
18
+ spec.metadata["source_code_uri"] = "https://github.com/civol/HDLRuby"
19
+ end
25
20
 
26
21
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
27
22
  f.match(%r{^(test|spec|features)/})
28
23
  end
24
+ spec.extra_rdoc_files = ["README.md"]
29
25
  spec.bindir = "exe"
30
26
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
27
  spec.require_paths = ["lib"]
data/README.md CHANGED
@@ -162,7 +162,7 @@ __Notes__:
162
162
  This introduction gives a glimpse of the possibilities of the language.
163
163
  However, we do recommend to consult the section about the [high-level programming features](#highfeat) to have a more complete view of the advanced possibilities of this language.
164
164
 
165
- At first glance, HDLRuby is similar to any other HDL languages (like Verilog HDL or VHDL), for instance the following code describes a simple D-FF:
165
+ At first glance, HDLRuby appears like any other HDL languages (like Verilog HDL or VHDL), for instance the following code describes a simple D-FF:
166
166
 
167
167
  ```ruby
168
168
  system :dff do
@@ -175,9 +175,9 @@ system :dff do
175
175
  end
176
176
  ```
177
177
 
178
- As it can be seen in the code above, `system` is the keyword used for describing a digital circuit. This keyword is an equivalent of the Verilog HDL `module`. In such a system, signals are declared using a `<type>.<direction>` construct where `type` is the data type of the signal (e.g., `bit` as in the code above) and `direction` indicates if the signal is an input, an output, an inout or an inner one; and executable blocks (similar to `always` block of Verilog HDL) are described using the `par` keyword when they are parallel and `seq` when they are sequential (i.e, with respectively non-blocking and blocking assignments).
178
+ As it can be seen in the code above, `system` is the keyword used for describing a digital circuit. This keyword is an equivalent of the Verilog HDL `module`. In such a system, signals are declared using a `<type>.<direction>` construct where `type` is the data type of the signal (e.g., `bit` as in the code above) and `direction` indicates if the signal is an input, an output, an inout or an inner one; and executable blocks (similar to `always` block of Verilog HDL) are described using the `par` keyword when they are parallel and `seq` when they are sequential (i.e., with respectively non-blocking and blocking assignments).
179
179
 
180
- After such a system has been defined, it can be instantiated. For axample a single instance of the `dff` system named `dff0` can be declared as follows:
180
+ After such a system has been defined, it can be instantiated. For example a single instance of the `dff` system named `dff0` can be declared as follows:
181
181
 
182
182
  ```ruby
183
183
  dff :dff0
@@ -204,8 +204,9 @@ system :counter2 do
204
204
 
205
205
  q <= dff1.q
206
206
  end
207
+ ```
207
208
 
208
- The instances can also be connected while being declared. For example the code above can be rewritten as follows:
209
+ The instances can also be connected while being declared. For example, the code above can be rewritten as follows:
209
210
 
210
211
  ```ruby
211
212
  system :counter2 do
@@ -222,7 +223,7 @@ In the code above, two possible connection methods are shown: for `dff0` ports a
222
223
  While a circuit can be generated from the code given above, a benchmark must
223
224
  be provided to test it. Such benchmark as described by constructs called
224
225
  timed behavior that give the evolution of signals depending of the time.
225
- For example the following code simulates the previous D-FF for 4 cycles
226
+ For example, the following code simulates the previous D-FF for 4 cycles
226
227
  of 20ns each, with reset on the first cycle, set of signal `d` to 1 for
227
228
  the third cycle and set of this signal to 0 for the last.
228
229
 
@@ -258,7 +259,7 @@ end
258
259
 
259
260
  ---
260
261
 
261
- The code describing a `dff` given above is not much different from its equivalent in other HDL. However, HDLRuby provides several features for achieving a higher productivity when describing hardware. We will now describe a few of them.
262
+ The code describing a `dff` given above is not much different from its equivalent in any other HDL. However, HDLRuby provides several features for achieving a higher productivity when describing hardware. We will now describe a few of them.
262
263
 
263
264
  First, several syntactic sugars exist that allow shorter code, for instance the following code is strictly equivalent to the previous description of `dff`:
264
265
 
@@ -324,7 +325,7 @@ system :reg do |typ|
324
325
  end
325
326
  ```
326
327
 
327
- Wait... I have just realized: a D-FF without any inverted output does not look very serious. So let us extend the existing `dff` to provide an inverted output. There are basically three ways for doing this. First, inheritance can be used: a new system is built inheriting from `dff` as it is done in the following code.
328
+ Wait... I have just realized: a D-FF without any inverted output does not look very serious. So, let us extend the existing `dff` to provide an inverted output. There are basically three ways for doing this. First, inheritance can be used: a new system is built inheriting from `dff` as it is done in the following code.
328
329
 
329
330
  ```ruby
330
331
  system :dff_full, dff do
@@ -417,7 +418,7 @@ system :sumprod_16_3456 do
417
418
  end
418
419
  ```
419
420
 
420
- The description above is straight forward, but it would be necessary to rewrite it if another circuit with different bit width or coefficients is to be designed. Moreover, if the number of coefficient is large an error in the expression will be easy to make and hard to find. A better approach would be to use a generic description of such a circuit as follows:
421
+ The description above is straight forward, but it would be necessary to rewrite it if another circuit with different bit width or coefficients is to be designed. Moreover, if the number of coefficients is large an error in the expression will be easy to make and hard to find. A better approach would be to use a generic description of such a circuit as follows:
421
422
 
422
423
  ```ruby
423
424
  system :sumprod do |typ,coefs|
@@ -443,7 +444,7 @@ sumprod(signed[32], [3,78,43,246, 3,67,1,8, 47,82,99,13, 5,77,2,4]).(:my_circuit
443
444
 
444
445
  As seen in the code above, when passing generic argument for instantiating a generic system, the name of the instance is put between brackets for avoiding confusion.
445
446
 
446
- While description `sumprod` is already usable in a wide range of cases, it still uses the standard addition and multiplication. However, there are cases where specific components are to be used for these operations, either for sake of performance, compliance with constraints, or because functionally different operations are required (e.g., saturated computations). This can be solved by using functions implementing such computation in place of operators, for example as follows:
447
+ While description `sumprod` is already usable in a wide range of cases, it still uses the standard addition and multiplication. However, there are cases where specific components are to be used for these operations, either for sake of performance, compliance with constraints, or because functionally different operations are required (e.g., saturated computations). This can be solved by using functions implementing such computation in place of operators, for example as follows:
447
448
 
448
449
  ```ruby
449
450
  system :sumprod_func do |typ,coefs|
@@ -457,7 +458,7 @@ system :sumprod_func do |typ,coefs|
457
458
  end
458
459
  ```
459
460
 
460
- Where `add` and `mult` are functions implementing the required specific operations. HDLRuby functions are similar to Verilog HDL ones. In our example, an addition that saturates at 1000 could be described as follows:
461
+ Where `add` and `mult` are functions implementing the required specific operations. HDLRuby functions are equivalent to the Verilog HDL ones. In our example, an addition that saturates at 1000 could be described as follows:
461
462
 
462
463
  ```ruby
463
464
  function :add do |x,y|
@@ -475,7 +476,7 @@ With HDLRuby functions, the result of the last statement in the return value, in
475
476
  hif(res>1000) { res <= 1000 }
476
477
  ```
477
478
 
478
- With functions, it is enough to change their content to obtained a new kind of circuit without change the main code. This approach suffers for two drawbacks though: first, the level of saturation is hard-coded in the function, second, it would be preferable to be able to select the function to execute instead of modifying its code. For the first problem a simple approach is to add an argument to the function given the saturation level. Such an add function would therefore be as follows:
479
+ With functions, it is enough to change their content to obtain a new kind of circuit without change the main code. This approach suffers for two drawbacks though: first, the level of saturation is hard coded in the function, second, it would be preferable to be able to select the function to execute instead of modifying its code. For the first problem a simple approach is to add an argument to the function given the saturation level. Such an add function would therefore be as follows:
479
480
 
480
481
  ```ruby
481
482
  function :add do |max, x, y|
@@ -489,7 +490,7 @@ end
489
490
 
490
491
  It would however be necessary to add this argument when invoking the function, e.g., `add(1000,sum,mult(...))`. While this argument is relevant for addition with saturation, it is not for the other kind of addition operations, and hence, the code of `sumprod` is not general any longer.
491
492
 
492
- HDLRuby provides two ways to address such issues. First, it is possible to pass code as argument. In the case of `sumprod` it would then be enough to add two arguments that perform the required addition and multiplication. The example is bellow:
493
+ HDLRuby provides two ways to address such issues. First, it is possible to pass code as argument. In the case of `sumprod` it would then be enough to add two arguments that perform the required addition and multiplication. The example is below:
493
494
 
494
495
  ```ruby
495
496
  system :sumprod_proc do |add,mult,typ,coefs|
@@ -534,7 +535,7 @@ sat16_1000.define_operator(:+) do |x,y|
534
535
  end
535
536
  ```
536
537
 
537
- In the code above, the first line define the new type `sat16_1000` to be 16-bit signed and the remaining overloads (redefines) the `+` operator for this type (the same should be done for the `*` operator).
538
+ In the code above, the first line defines the new type `sat16_1000` to be 16-bit signed and the remaining overloads (redefines) the `+` operator for this type (the same should be done for the `*` operator).
538
539
  Then, the initial version of `sumprod` can be used with this type to achieve saturated computations as follows:
539
540
 
540
541
  ```ruby
@@ -587,18 +588,18 @@ dff_single.systemT.instantiate(:dff_not_single)
587
588
  In the above example, `dff_not_single` is declared to be an instance
588
589
  of the same system as `dff_single`.
589
590
 
590
- This reflection capability can also be used for instance for accessing the
591
+ This reflection capability can also be used for instance, for accessing the
591
592
  data type of a signal (`sig.type`), but also the current basic block
592
593
  (`cur_block`), the current process (`cur_behavior`) and so on.
593
594
  The standard library of HDLRuby, that includes several hardware constructs
594
- like final state machine descriptors, is mainly based on using these
595
+ like finite state machine descriptors, is mainly based on using these
595
596
  reflection features.
596
597
 
597
598
 
598
599
 
599
600
  ## How does HDLRuby work
600
601
 
601
- Contrary to descriptions in high-level HDL like SystemVerilog, VHDL or SystemC, HDLRuby descriptions are not software-like description of hardware, but are programs meant to produce hardware descriptions. In other words, while the execution of a common HDL code will result in some simulation of the described hardware, the execution of HDLRuby code will result in some low-level hardware description. This low-level description is synthesizable, and can also be simulated like any standard hardware description.
602
+ Contrary to descriptions in high-level HDL like SystemVerilog, VHDL or SystemC, HDLRuby descriptions are not software-like description of hardware, but are programs meant to produce hardware descriptions. In other words, while the execution of a common HDL code will result in some simulation of the described hardware, the execution of HDLRuby code will result in some low-level hardware description. This low-level description is synthesizable and can also be simulated like any standard hardware description.
602
603
  This decoupling of the representation of the hardware from the point of view of the user (HDLRuby), and the actual hardware description (HDLRuby::Low) makes it possible to provide the user with any advanced software features without jeopardizing the synthesizability of the actual hardware description.
603
604
 
604
605
  For that purpose, each construct in HDLRuby is not a direct description of some hardware construct, but a program which generates the corresponding description. For example, let us consider the following line of code of HDLRuby describing the connection between signal `a` and signal `b`:
@@ -607,7 +608,7 @@ For that purpose, each construct in HDLRuby is not a direct description of some
607
608
  a <= b
608
609
  ```
609
610
 
610
- Its execution will produce the actual hardware description of this connection as an object of the HDLRuby::Low library — in this case an instance of the `HDLRuby::Low::Connection` class. Concretely, a HDLRuby system is described by a Ruby block, and the instantiation of this system is actually performed by executing this block. The actual synthesizable description of this hardware is the execution result of this instantiation.
611
+ Its execution will produce the actual hardware description of this connection as an object of the HDLRuby::Low library — in this case an instance of the `HDLRuby::Low::Connection` class. Concretely, a HDLRuby system is described by a Ruby block, and the instantiation of this system is performed by executing this block. The actual synthesizable description of this hardware is the execution result of this instantiation.
611
612
 
612
613
 
613
614
 
@@ -625,7 +626,7 @@ has been declared with `:hello` as name, it will be afterward referred by `hello
625
626
 
626
627
  A system represents a digital system and corresponds to a Verilog HDL module. A system has an interface comprising input, output, and inout signals, and includes of structural and behavioral descriptions.
627
628
 
628
- A signal represents a state in a system. It has a data type and a value, the latter varying with time. Similarly to VHDL, HDLRuby signals can be viewed as abstractions of both wires and registers in a digital circuit. As a general rule, a signal whose value is explicitly set all the time models a wire, otherwise it models a register.
629
+ A signal represents a state in a system. It has a data type and a value, the latter varying with time. HDLRuby signals can be viewed as abstractions of both wires and registers in a digital circuit. As general rule, a signal whose value is explicitly set all the time models a wire, otherwise it models a register.
629
630
 
630
631
  ### Declaring an empty system
631
632
 
@@ -731,7 +732,7 @@ A connection between signals is done using the arrow operator `<=` as follows:
731
732
 
732
733
  The `<destination>` must be a reference to a signal, and the `<source>` can be any expression.
733
734
 
734
- For example the following code, connects signal `w1` to signal `ready` and signal `clk` to the first bit of signal `w2`:
735
+ For example, the following code connects signal `w1` to signal `ready` and signal `clk` to the first bit of signal `w2`:
735
736
 
736
737
  ```ruby
737
738
  ready <= w1
@@ -817,7 +818,7 @@ end
817
818
 
818
819
  The signals of the interface of signals are accessible from anywhere in a HDLRuby description. This is not the case for inner signals and instances: they are accessible only within the scope they are declared in.
819
820
 
820
- A scope is a region of the code where locally declared objects are accessible. Each system has its own scope that cannot be accessible from other part of an HDLRuby description. For example in the following code, signals `d` and `qb` as well as instance `dffI` cannot be accessed from outside system `div2`:
821
+ A scope is a region of the code where locally declared objects are accessible. Each system has its own scope that cannot be accessible from other part of an HDLRuby description. For example, in the following code signals `d` and `qb` as well as instance `dffI` cannot be accessed from outside system `div2`:
821
822
 
822
823
  ```ruby
823
824
  system :div2 do
@@ -839,7 +840,7 @@ sub do
839
840
  end
840
841
  ```
841
842
 
842
- For example, in the code bellow, signal `sig` is not accessible from outside the additional inner scope of system `sys`
843
+ For example, in the code bellow signal `sig` is not accessible from outside the additional inner scope of system `sys`
843
844
 
844
845
  ```ruby
845
846
  system :sys do
@@ -885,10 +886,10 @@ end
885
886
 
886
887
  Where:
887
888
 
888
- - `<name>` is the name of the scope.
889
- - `<code>` is the code within the scope.
889
+ * `<name>` is the name of the scope.
890
+ * `<code>` is the code within the scope.
890
891
 
891
- Contrary to the case of scopes without name, signals and instances declared within a named scope can be accessed outside using this name as reference. For example in the code bellow signal `sig` declared within scope named `scop` is accessed outside it using `scop.sig`:
892
+ Contrary to the case of scopes without name, signals and instances declared within a named scope can be accessed outside using this name as reference. For example, in the code bellow signal `sig` declared within scope named `scop` is accessed outside it using `scop.sig`:
892
893
 
893
894
  ```ruby
894
895
  sub :scop do
@@ -917,7 +918,7 @@ While such signals will be physically linked to the system, they are only access
917
918
 
918
919
  An event represents a specific change of state of a signal.
919
920
  For example, a rising edge of a clock signal named `clk` will be represented by event `clk.posedge`. In HDLRuby, events are obtained directly from
920
- expressions using the following methods: `posedge` for rising edge, `negedge` for falling edge, and `edge` for any edge.
921
+ expressions using the following methods: `posedge` for rising edge, `negedge` for falling edge, and `edge` for any edge.
921
922
  Events are described in more detail in section [Events](#events).
922
923
 
923
924
  When one of the events of the sensitivity list of a behavior occurs, the behavior is executed, i.e., each of its statements is executed in sequence. A statement can represent a data transmission to a signal, a control flow, a nested execution block or the declaration of an inner signal (as stated
@@ -929,10 +930,10 @@ A transmission statement is declared using the arrow operator `<=` as follows:
929
930
  <destination> <= <source>
930
931
  ```
931
932
 
932
- The `<destination>` must be a reference to a signal, and the `<source>` can be any expression. A transmission has therefore exactly the same structure as a connection. However, its execution model is different: whereas a connection is continuously executed, a transmission is only executed during the execution of its block.
933
+ The `<destination>` must be a reference to a signal, and the `<source>` can be any expression. A transmission has therefore the same structure as a connection. However, its execution model is different: whereas a connection is continuously executed, a transmission is only executed during the execution of its block.
933
934
 
934
935
  A block comprises a list of statements. It is used for adding hierarchy within a behavior. Blocks can be either parallel or sequential, i.e., their transmission statements are respectively non-blocking or blocking.
935
- By default, a top block is created when declaring a behavior, and it inherits from its execution mode. For example, with the following code, the top block of the behavior is sequential.
936
+ By default, a top block is created when declaring a behavior, and it inherits from its execution mode. For example, with the following code the top block of the behavior is sequential.
936
937
 
937
938
  ```ruby
938
939
  system :with_sequential_behavior do
@@ -956,7 +957,7 @@ system :with_sequential_behavior do
956
957
  end
957
958
  ```
958
959
 
959
- A sub block can also have a different execution mode if it is declared using `seq`, that will force sequential execution mode, and `par` that will force parallel execution mode. For example in the following code, a parallel sub block is declared within a sequential one:
960
+ A sub block can also have a different execution mode if it is declared using `seq`, that will force sequential execution mode, and `par` that will force parallel execution mode. For example, in the following code a parallel sub block is declared within a sequential one:
960
961
 
961
962
  ```ruby
962
963
  system :with_sequential_behavior do
@@ -969,7 +970,7 @@ system :with_sequential_behavior do
969
970
  end
970
971
  ```
971
972
 
972
- Sub blocks have their own scope so that it is possible to declare signals without colliding with existing ones. For example it is possible to
973
+ Sub blocks have their own scope so that it is possible to declare signals without colliding with existing ones. For example, it is possible to
973
974
  declare three different inner signals all called `sig` as follows:
974
975
 
975
976
  ```ruby
@@ -1010,7 +1011,7 @@ system :shift16 do
1010
1011
  end
1011
1012
  ```
1012
1013
 
1013
- In the example above, the order of the transmission statements is of no consequence. This is not the case for the following example, that implements the same register using a sequential block. In this second example, putting statement `reg[0] <= din` in the last place would have lead to an invalid functionality for a shift register.
1014
+ In the example above, the order of the transmission statements is of no consequence. This is not the case for the following example, that implements the same register using a sequential block. In this second example, putting statement `reg[0] <= din` in the last place would have led to an invalid functionality for a shift register.
1014
1015
 
1015
1016
  ```ruby
1016
1017
  system :shift16 do
@@ -1050,7 +1051,7 @@ In such a case, the description can be shortened using the `at` operator as foll
1050
1051
  ( statement ).at(<list of events>)
1051
1052
  ```
1052
1053
 
1053
- For example the following two code samples are equivalent:
1054
+ For example, the following two code samples are equivalent:
1054
1055
 
1055
1056
  ```ruby
1056
1057
  par(clk.posedge) do
@@ -1109,24 +1110,24 @@ that changes the execution flow of the behavior, the block statement (described
1109
1110
 
1110
1111
  __Note__:
1111
1112
 
1112
- - There is actually a fifth type of statement, the time statement. It will be discussed in section [Time](#time).
1113
+ - There is a fifth type of statement, named the time statement, that will be discussed in section [Time](#time).
1113
1114
 
1114
1115
 
1115
1116
  ### Transmit statement
1116
1117
 
1117
1118
  A transmit statement is declared using the arrow operator `<=` within a behavior. Its right value is the expression to compute and its left value is a reference to the target signals (or parts of signals), i.e., the signals (or part of signals) that receive the computation result.
1118
1119
 
1119
- For example following code transmits the value `3` to signal `s0` and the sum of the values of signals `i0` and `i1` to the first four bits of signal `s1`:
1120
+ For example, following code transmits the value `3` to signal `s0` and the sum of the values of signals `i0` and `i1` to the first four bits of signal `s1`:
1120
1121
 
1121
1122
  ```ruby
1122
1123
  s0 <= 3
1123
1124
  s1[3..0] <= i0 + i1
1124
1125
  ```
1125
1126
 
1126
- The comportment of a transmit statement depends on the execution mode of the enclosing block:
1127
+ The behavior of a transmit statement depends on the execution mode of the enclosing block:
1127
1128
 
1128
- - If the mode is parallel, the target signals are updated when all the statements of the current block are processed.
1129
- - If the mode is sequential, the target signals are updated immediately after the right value of the statement is computed.
1129
+ * If the mode is parallel, the target signals are updated when all the statements of the current block are processed.
1130
+ * If the mode is sequential, the target signals are updated immediately after the right value of the statement is computed.
1130
1131
 
1131
1132
 
1132
1133
  ### Control statements
@@ -1187,12 +1188,12 @@ end
1187
1188
  #### About loops
1188
1189
 
1189
1190
  HDLRuby does not include any hardware construct for describing loops. This might look poor compared to the other HDL, but it is important to understand
1190
- that the current synthesis tools do not really synthesize hardware from such loops but instead preprocess them (e.g., unroll them) to synthesizable loopless hardware. In HDLRuby, such features are natively supported by the Ruby loop constructs (`for`, `while`, and so on), but also by advanced Ruby constructs like the enumerators (`each`, `times`, and so on).
1191
+ that the current synthesis tools do not really synthesize hardware from such loops but instead preprocess them (e.g., unroll them) to synthesizable loop less hardware. In HDLRuby, such features are natively supported by the Ruby loop constructs (`for`, `while`, and so on), but also by advanced Ruby constructs like the enumerators (`each`, `times`, and so on).
1191
1192
 
1192
1193
  __Notes__:
1193
1194
 
1194
1195
  - HDLRuby being based on Ruby, it is highly recommended to avoid `for` or `while` constructs and to use enumerators instead.
1195
- - The Ruby `if` and `case` statements can also be used, but they do not represent nay hardware. Actually, they are executed when the corresponding system is instantiated. For example, the following code will display `Hello world!` when the described system is instantiated, provided the generic parameter `param` is not nil.
1196
+ - The Ruby `if` and `case` statements can also be used, but they do not represent any hardware. In fact, they are executed when the corresponding system is instantiated. For example, the following code will display `Hello world!` when the described system is instantiated, provided the generic parameter `param` is not nil.
1196
1197
 
1197
1198
  ```ruby
1198
1199
  system :say_hello do |param = nil|
@@ -1206,11 +1207,11 @@ __Notes__:
1206
1207
  <a name="types"></a>
1207
1208
 
1208
1209
  Each signal and expression is associated with a data type which describes the kind of value it can represent. In HDLRuby, the data types represent
1209
- basically bit vectors associated with the way they should be interpreted, i.e., as bit strings, unsigned values, signed values, or hierarchical contents.
1210
+ bit vectors associated with the way they should be interpreted, i.e., as bit strings, unsigned values, signed values, or hierarchical contents.
1210
1211
 
1211
1212
  ### Type construction
1212
1213
 
1213
- There are five basic types, `bit`, `signed`, `unsigned`, `integer` and `float` that represent respectively single bit logical values, single bit unsigned values, single bit signed values, Ruby integer values and Ruby floating point values (double precision). The first three types are HW and support four-valued logic, whereas the two last ones are SW (but are compatible with HW) and only support boolean logic. Ruby integers can represent any element of **Z** (the mathematical integers), and have for that purpose a variable bit-width.
1214
+ There are five basic types, `bit`, `signed`, `unsigned`, `integer` and `float` that represent respectively single bit logical values, single bit unsigned values, single bit signed values, Ruby integer values and Ruby floating-point values (double precision). The first three types are HW and support four-valued logic, whereas the two last ones are SW (but are compatible with HW) and only support Boolean logic. Ruby integers can represent any element of **Z** (the mathematical integers) and have for that purpose a variable bit-width.
1214
1215
 
1215
1216
 
1216
1217
  The other types are built from them using a combination of the two following
@@ -1223,14 +1224,14 @@ __The vector operator__ `[]` is used for building types representing vectors of
1223
1224
  ```
1224
1225
 
1225
1226
  The `<range>` of a vector type indicates the position of the starting and ending bits relatively to the radix point. If the position of the starting bit
1226
- is on the left side of the range, the vector is big endian, otherwise it is little endian. Negative values in a range are also possible and indicate positions bellow the radix point. For example the following code describes a big endian fixed point type with 8 bits above the radix point and 4 bits
1227
+ is on the left side of the range, the vector is big endian, otherwise it is little endian. Negative values in a range are also possible and indicate positions bellow the radix point. For example, the following code describes a big-endian fixed-point type with 8 bits above the radix point and 4 bits
1227
1228
  bellow:
1228
1229
 
1229
1230
  ```ruby
1230
1231
  bit[7..-4]
1231
1232
  ```
1232
1233
 
1233
- A `n..0` range can also be abbreviated to `n+1`. For instance the two following types are identical:
1234
+ A `n..0` range can also be abbreviated to `n+1`. For instance, the two following types are identical:
1234
1235
 
1235
1236
  ```ruby
1236
1237
  bit[7..0]
@@ -1243,7 +1244,7 @@ A vector of multiple types, also called tuple, is declared as follows:
1243
1244
  [<type 0>, <type 1>, ... ]
1244
1245
  ```
1245
1246
 
1246
- For example the following code declares the type of the vectors made of a 8-bit logical, a 16-bit signed and a 16-bit unsigned values:
1247
+ For example, the following code declares the type of the vectors made of a 8-bit logical, a 16-bit signed and a 16-bit unsigned values:
1247
1248
 
1248
1249
  ```ruby
1249
1250
  [ bit[8], signed[16], unsigned[16] ]
@@ -1270,7 +1271,7 @@ It is possible to give names to type constructs using the `typedef` keywords as
1270
1271
  <type construct>.typedef :<name>
1271
1272
  ```
1272
1273
 
1273
- For example the followings gives the name `char` to a signed 8-bit vector:
1274
+ For example, the followings gives the name `char` to a signed 8-bit vector:
1274
1275
 
1275
1276
  ```ruby
1276
1277
  signed[7..0].typedef :char
@@ -1292,9 +1293,8 @@ end
1292
1293
 
1293
1294
  Where:
1294
1295
 
1295
- - `type name` is the name of the type
1296
-
1297
- - `code` is a description of the content of the type
1296
+ * `type name` is the name of the type
1297
+ * `code` is a description of the content of the type
1298
1298
 
1299
1299
  For example, the previous `char` could have been declared as follows:
1300
1300
 
@@ -1308,7 +1308,7 @@ end
1308
1308
 
1309
1309
  The basis of all the types in HDLRuby is the vector of bits (bitvector) where each bit can have four values: 0, 1, Z and X (for undefined). Bit vectors are by default unsigned but can be set to be signed. When performing computations between signals of different bitvector type, the shorter signal is extended to the size of the larger one preserving its sign if it is signed.
1310
1310
 
1311
- While the underlying structure of any HDLRuby type is the bitvector, complex types can be be defined. When using such types in computational expressions and assignments they are first implicitly converted to an unsigned bit vector of the same size.
1311
+ While the underlying structure of any HDLRuby type is the bitvector, complex types can be defined. When using such types in computational expressions and assignments they are first implicitly converted to an unsigned bit vector of the same size.
1312
1312
 
1313
1313
  ## Expressions
1314
1314
  <a name="expressions"></a>
@@ -1320,7 +1320,7 @@ They include [immediate values](#values), [reference to signals](#references) an
1320
1320
  ### Immediate values
1321
1321
  <a name="values"></a>
1322
1322
 
1323
- The immediate values of HDLRuby can represent vectors of `bit`, `unsigned` and `signed`, and integer or floating point numbers. They are prefixed by a `_` character and include a header that indicates the vector type and the base used for representing the value, followed by a numeral representing the value. The bit width of a value is obtained by default from the width of the numeral, but it is also possible to enforce it in the header.
1323
+ The immediate values of HDLRuby can represent vectors of `bit`, `unsigned` and `signed`, and integer or floating-point numbers. They are prefixed by a `_` character and include a header that indicates the vector type and the base used for representing the value, followed by a numeral representing the value. The bit width of a value is obtained by default from the width of the numeral, but it is also possible to enforce it in the header.
1324
1324
 
1325
1325
  The vector type specifiers are the followings:
1326
1326
 
@@ -1355,7 +1355,7 @@ _s8o144
1355
1355
 
1356
1356
  __Notes__:
1357
1357
 
1358
- - Ruby immediate values can also be used, their bit width is automatically adjusted to match the data type of the expression they are used in. Please notice this adjusting may change the value of the immediate, for example the following code will actually set `sig` to 4 instead of 100:
1358
+ - Ruby immediate values can also be used, their bit width is automatically adjusted to match the data type of the expression they are used in. Please notice this adjusting may change the value of the immediate, for example the following code will set `sig` to 4 instead of 100:
1359
1359
 
1360
1360
  ```ruby
1361
1361
  [3..0].inner :sig
@@ -1368,7 +1368,7 @@ __Notes__:
1368
1368
 
1369
1369
  References are expressions used to designate signals, or a part of signals.
1370
1370
 
1371
- The most simple reference is simply the name of a signal. It designates the signal corresponding to this name in the current scope. For instance, in the
1371
+ The simplest reference is simply the name of a signal. It designates the signal corresponding to this name in the current scope. For instance, in the
1372
1372
  following code, inner signal `sig0` is declared, and therefore the name *sig0* becomes a reference to designate this signal.
1373
1373
 
1374
1374
  ```ruby
@@ -1409,7 +1409,7 @@ end
1409
1409
  <a name="operators"></a>
1410
1410
 
1411
1411
  The following table gives a summary of the operators available in HDLRuby.
1412
- More details are given for each group of operator in the subsequent sections.
1412
+ More details are given for each group of operators in the subsequent sections.
1413
1413
 
1414
1414
  __Assignment operators (left-most operator of a statement):__
1415
1415
 
@@ -1488,7 +1488,7 @@ __Notes__:
1488
1488
  #### Assignment operators
1489
1489
  <a name="assignment"></a>
1490
1490
 
1491
- The assignment operators can be used with any type. They are actually the connection and the transmission operators, both being represented by `<=`.
1491
+ The assignment operators can be used with any type. They are the connection and the transmission operators both being represented by `<=`.
1492
1492
 
1493
1493
  __Note__:
1494
1494
 
@@ -1516,17 +1516,17 @@ __Notes__:
1516
1516
  #### Logic and shift operators
1517
1517
  <a name="logic"></a>
1518
1518
 
1519
- In HDLRuby, the logic operators are all bitwise. For performing boolean computations it is necessary to use single bit values. The bitwise logic binary operators are `&`, `|`, and `^`, and the unary one is `~`. They have the same meaning as their Ruby equivalents.
1519
+ In HDLRuby, the logic operators are all bitwise. For performing Boolean computations it is necessary to use single bit values. The bitwise logic binary operators are `&`, `|`, and `^`, and the unary one is `~`. They have the same meaning as their Ruby equivalents.
1520
1520
 
1521
- __Note__: there is two reasons why there is no boolean operators
1521
+ __Note__: there is two reasons why there is no Boolean operators
1522
1522
 
1523
- 1. Ruby language does not support redefinition of the boolean operators
1523
+ 1. Ruby language does not support redefinition of the Boolean operators
1524
1524
 
1525
- 2. In Ruby, each value which is not `false` nor `nil` is considered to be true. This is perfectly relevant for software, but not for hardware where the basic data types are bit vectors. Hence, it seemed preferable to support boolean computation for one-bit values only, which can be done through bitwise operations.
1525
+ 2. In Ruby, each value which is not `false` nor `nil` is assumed to be true. This is perfectly relevant for software, but not for hardware where the basic data types are bit vectors. Hence, it seemed preferable to support Boolean computation for one-bit values only, which can be done through bitwise operations.
1526
1526
 
1527
- The shift operators are `<<` and `>>` and have the same meaning as their Ruby equivalent. They do not change the bit width, and preserve the sign for `signed` values.
1527
+ The shift operators are `<<` and `>>` and have the same meaning as their Ruby equivalent. They do not change the bit width and preserve the sign for `signed` values.
1528
1528
 
1529
- The rotation operators are `rl` and `rr` for respectively left and right bit rotations. Like the shifts, they do not change the bit width and preserve the sign for the `signed` values. However, since such operators do not exist in Ruby, they are actually used like methods as follows:
1529
+ The rotation operators are `rl` and `rr` for respectively left and right bit rotations. Like the shifts, they do not change the bit width and preserve the sign for the `signed` values. However, since such operators do not exist in Ruby, they are used like methods as follows:
1530
1530
 
1531
1531
  ```ruby
1532
1532
  <expression>.rl(<other expression>)
@@ -1561,7 +1561,7 @@ These operators comprise the bit width conversions: `ljust`, `rjust`, `zext` and
1561
1561
 
1562
1562
  More precisely, the bit width conversions operate as follows:
1563
1563
 
1564
- - `ljust` and `rjust` increase the size from respectively the left or the right side of the bit vector. They take as argument the width of the new type and the value (0 or 1) of the bits to add. For example the following code increases the size of `sig0` to 12 bits by adding 1 on the right:
1564
+ - `ljust` and `rjust` increase the size from respectively the left or the right side of the bit vector. They take as argument the width of the new type and the value (0 or 1) of the bits to add. For example, the following code increases the size of `sig0` to 12 bits by adding 1 on the right:
1565
1565
 
1566
1566
  ```ruby
1567
1567
  [7..0].inner :sig0
@@ -1702,7 +1702,7 @@ __Multiplicative operators:__
1702
1702
 
1703
1703
  ### HDLRuby functions
1704
1704
 
1705
- Similarly to Verilog HDL, HDLRuby provides function constructs for reusing code. HDLRuby functions are declared as follows:
1705
+ Like Verilog HDL, HDLRuby provides function constructs for reusing code. HDLRuby functions are declared as follows:
1706
1706
 
1707
1707
  ```ruby
1708
1708
  function :<function name> do |<arguments>|
@@ -1712,21 +1712,21 @@ Similarly to Verilog HDL, HDLRuby provides function constructs for reusing code.
1712
1712
 
1713
1713
  Where:
1714
1714
 
1715
- - `function name` is the name of the function.
1716
- - `arguments` is the list of arguments of the function.
1717
- - `code` is the code of the function.
1715
+ * `function name` is the name of the function.
1716
+ * `arguments` is the list of arguments of the function.
1717
+ * `code` is the code of the function.
1718
1718
 
1719
1719
  __Notes__:
1720
1720
 
1721
1721
  - Functions have their own scope, so that any declaration within a function is local. It is also forbidden to declare interface signals (input, output or inout) within a function.
1722
1722
 
1723
- - Similarly to Ruby proc objects, the last statement of a function's code serves as return value. For instance the following function returns `1` (in this example the function does not have any argument):
1723
+ - Like the Ruby proc objects, the last statement of a function's code serves as return value. For instance, the following function returns `1` (in this example the function does not have any argument):
1724
1724
 
1725
1725
  ```ruby
1726
1726
  function :one { 1 }
1727
1727
  ```
1728
1728
 
1729
- - Functions can accept any kind of object as argument, including variadic arguments or blocks of code as shown bellow with a function which apply the code passed as argument to all the variadic arguments of `args`:
1729
+ - Functions can accept any kind of object as argument, including variadic arguments or blocks of code as shown below with a function which apply the code passed as argument to all the variadic arguments of `args`:
1730
1730
 
1731
1731
  ```ruby
1732
1732
  function :apply do |*args, &code|
@@ -1758,12 +1758,12 @@ end
1758
1758
  ```
1759
1759
  Where:
1760
1760
 
1761
- - `function name` is the name of the function.
1762
- - `arguments` is the list of arguments of the function.
1763
- - `code` is the code of the function.
1761
+ * `function name` is the name of the function.
1762
+ * `arguments` is the list of arguments of the function.
1763
+ * `code` is the code of the function.
1764
1764
 
1765
- These functions are called the same way HDLRuby functions are called, but this operation actually pastes the code of the function as is within the code.
1766
- Moreover, these function do not have any scope so that any inner signal or instance declared within them will actually added to the object they are invoked in.
1765
+ These functions are called the same way HDLRuby functions are called, but this operation pastes the code of the function as is within the code.
1766
+ Moreover, these functions do not have any scope so that any inner signal or instance declared within them will be added to the object they are invoked in.
1767
1767
 
1768
1768
  For example, the following function will add input `in0` to any system where it is invoked:
1769
1769
 
@@ -1805,7 +1805,7 @@ system :sys do
1805
1805
  end
1806
1806
  ```
1807
1807
 
1808
- Ruby functions can be compared to the macros of the C languages: they have more flexible since they actually edit the code they are invoked in, but are also dangerous to use. In general, it is not recommended to use them, unless when designing a library of generic code for HDLRuby.
1808
+ Ruby functions can be compared to the macros of the C languages: they are more flexible since they edit the code they are invoked in, but they are also dangerous to use. In general, it is not recommended to use them, unless when designing a library of generic code for HDLRuby.
1809
1809
 
1810
1810
 
1811
1811
  ## Time
@@ -1814,7 +1814,7 @@ Ruby functions can be compared to the macros of the C languages: they have more
1814
1814
  ### Time values
1815
1815
  <a name="time_val"></a>
1816
1816
 
1817
- In HDLRuby, time values can be created using the time operators: `s` for seconds, `ms` for millisecond, `us` for microsecond, `ns` for nano second, `ps` for pico second and `fs` for femto second. For example, the followings are all indicating one second of time:
1817
+ In HDLRuby, time values can be created using the time operators: `s` for seconds, `ms` for millisecond, `us` for microseconds, `ns` for nanoseconds, `ps` for picoseconds. For example, the followings are all indicating one second of time:
1818
1818
 
1819
1819
  ```ruby
1820
1820
  1.s
@@ -1822,14 +1822,13 @@ In HDLRuby, time values can be created using the time operators: `s` for seconds
1822
1822
  1000000.us
1823
1823
  1000000000.ns
1824
1824
  1000000000000.ps
1825
- 1000000000000000.fs
1826
1825
  ```
1827
1826
 
1828
1827
 
1829
1828
  ### Time behaviors and time statements
1830
1829
  <a name="time_beh"></a>
1831
1830
 
1832
- Similarly to the other HDL, HDLRuby provides specific statements that models the advance of time. These statements are not synthesizable and are used for simulating the environment of a hardware component. For sake of clarity, such statements are only allowed in explicitly non-synthesizable behavior declared using the `timed` keyword as follows.
1831
+ Like the other HDL, HDLRuby provides specific statements that models the advance of time. These statements are not synthesizable and are used for simulating the environment of a hardware component. For sake of clarity, such statements are only allowed in explicitly non-synthesizable behavior declared using the `timed` keyword as follows.
1833
1832
 
1834
1833
  ```ruby
1835
1834
  timed do
@@ -1837,12 +1836,10 @@ timed do
1837
1836
  end
1838
1837
  ```
1839
1838
 
1840
- A time behavior do not have any sensitivity list but it can include any statement supported by a standard behavior in addition to the time statements.
1839
+ A time behavior does not have any sensitivity list but it can include any statement supported by a standard behavior in addition to the time statements.
1841
1840
  There are two kinds of such statements:
1842
1841
 
1843
- - The `wait` statements: such a statement blocks the execution of the behavior
1844
- for the amount of time given in argument. For example the following code
1845
- waits 10ns before proceeding:
1842
+ - The `wait` statements: such a statement blocks the execution of the behavior for the time given in argument. For example the following code waits 10ns before proceeding:
1846
1843
 
1847
1844
  ```ruby
1848
1845
  wait(10.ns)
@@ -1865,7 +1862,7 @@ There are two kinds of such statements:
1865
1862
 
1866
1863
  ### Parallel and sequential execution
1867
1864
 
1868
- Time behaviors are by default sequential but they can include both parallel and
1865
+ Time behaviors are by default sequential, but they can include both parallel and
1869
1866
  sequential blocks. The execution semantic is the following:
1870
1867
 
1871
1868
  - A sequential block in a time behavior is executed sequentially.
@@ -1926,7 +1923,7 @@ system :something do |t,w,s|
1926
1923
  end
1927
1924
  ```
1928
1925
 
1929
- It is also possible to use a variable number of generic parameters using the variadic operator `*` like in the following example. In this examples, `args` is an array containing an indefinite number of parameters.
1926
+ It is also possible to use a variable number of generic parameters using the variadic operator `*` like in the following example. In this example, `args` is an array containing an indefinite number of parameters.
1930
1927
 
1931
1928
  ```ruby
1932
1929
  system(:variadic) { |*args| }
@@ -2005,7 +2002,7 @@ If less values are provided than the number of generic arguments, the type is pa
2005
2002
  In HDLRuby, a system can inherit from the content of one or several other parent systems using the `include` command as follows: `include <list of
2006
2003
  systems>`. Such an include can be put anywhere in the body of a system, but the resulting content will be accessible only after this command.
2007
2004
 
2008
- For example, the following code describes first a simple D-FF, and then use it to described a FF with an additional reversed output (`qb`):
2005
+ For example, the following code describes first a simple D-FF, and then use it to describe a FF with an additional reversed output (`qb`):
2009
2006
 
2010
2007
  ```ruby
2011
2008
  system :dff do
@@ -2024,7 +2021,7 @@ system :dff_full do
2024
2021
  end
2025
2022
  ```
2026
2023
 
2027
- It is also possible to declare inheritance in a more object oriented fashion by listing the parents of a system just after declaring its name as follows:
2024
+ It is also possible to declare inheritance in a more object-oriented fashion by listing the parents of a system just after declaring its name as follows:
2028
2025
 
2029
2026
  ```ruby
2030
2027
  system :<new system name>, <list of parent systems> do
@@ -2044,12 +2041,12 @@ end
2044
2041
 
2045
2042
  __Note__:
2046
2043
 
2047
- - As a matter of implementation, HDLRuby systems can be seen as set of methods used for accessing various constructs (signals, instances). Hence inheritance in HDLRuby is actually closer the Ruby mixin mechanism than to a true software inheritance.
2044
+ * As a matter of implementation, HDLRuby systems can be viewed as sets of methods used for accessing various constructs (signals, instances). Hence inheritance in HDLRuby is closer the Ruby mixin mechanism than to a true software inheritance.
2048
2045
 
2049
2046
 
2050
2047
  #### About inner signals and system instances
2051
2048
 
2052
- By default, inner signals and instances of a parent system are not accessible by its child systems. They can be made accessible using the `export` keyword as follows: `export <symbol 0>, <symbol 1>, ...` . For example the following
2049
+ By default, inner signals and instances of a parent system are not accessible by its child systems. They can be made accessible using the `export` keyword as follows: `export <symbol 0>, <symbol 1>, ...` . For example, the following
2053
2050
  code exports signals `clk` and `rst` and instance `dff0` of system `exporter` so that they can be accessed in child system `importer`.
2054
2051
 
2055
2052
  ```ruby
@@ -2088,7 +2085,7 @@ __Note__:
2088
2085
 
2089
2086
  #### Conflicts when inheriting
2090
2087
 
2091
- Signals and instances cannot be overridden, this is also the case for signals and instances accessible through inheritance. For example the following code is invalid since `rst` has already been defined in `dff`:
2088
+ Signals and instances cannot be overridden, this is also the case for signals and instances accessible through inheritance. For example, the following code is invalid since `rst` has already been defined in `dff`:
2092
2089
 
2093
2090
  ```ruby
2094
2091
  system :dff_bad, dff do
@@ -2102,11 +2099,11 @@ section.
2102
2099
 
2103
2100
  #### Shadowed signals and instances
2104
2101
 
2105
- It is possible in HDLRuby to declare a signal or an instance whose name is identical to one used in one of the included systems. In such a case, the corresponding construct of the included system is still present, but is not directly accessible even if exported, they are said to be shadowed.
2102
+ It is possible in HDLRuby to declare a signal or an instance whose name is identical to one used in one of the included systems. In such a case, the corresponding construct of the included system is still present, but it is not directly accessible even if exported, they are said to be shadowed.
2106
2103
 
2107
2104
  In order to access to the shadowed signals or instances, a system must be reinterpreted as the relevant parent system using the `as` operator as follows: `as(system)`.
2108
2105
 
2109
- For example, in the following code signal `db` of system `dff_db` is shadowed by signal `db` of system `dff_shadow`, but is accessed using the `as` operator.
2106
+ For example, in the following code signal `db` of system `dff_db` is shadowed by signal `db` of system `dff_shadow`, but it is accessed using the `as` operator.
2110
2107
 
2111
2108
  ```ruby
2112
2109
  system :dff_db do
@@ -2153,7 +2150,7 @@ end
2153
2150
  ### Opening an instance
2154
2151
  <a name="instance_open"></a>
2155
2152
 
2156
- When there is a modification to apply to an instance, it is sometimes preferable to modify this sole instance rather than declaring a all new system to derivate the instance from. For that purpose it is possible to open an instance for modification as follows:
2153
+ When there is a modification to apply to an instance, it is sometimes preferable to modify this sole instance rather than declaring a new system to derivate the instance from. For that purpose, it is possible to open an instance for modification as follows:
2157
2154
 
2158
2155
  ```ruby
2159
2156
  <instance name>.open do
@@ -2183,19 +2180,19 @@ Operators can be overloaded for specific types. This allows for instance to supp
2183
2180
  An operator is redefined as follows:
2184
2181
 
2185
2182
  ```ruby
2186
- <type>.define_operaot(:<op>) do |<args>|
2183
+ <type>.define_operator(:<op>) do |<args>|
2187
2184
  <operation description>
2188
2185
  end
2189
2186
  ```
2190
2187
 
2191
2188
  Where:
2192
2189
 
2193
- - `type` is the type from which the operation is overloaded.
2194
- - `op` is the operator that is overloaded (e.g., `+`)
2195
- - `args` are the arguments of the operation.
2196
- - `operation description` is an HDLRuby description of the new operation.
2190
+ * `type` is the type from which the operation is overloaded.
2191
+ * `op` is the operator that is overloaded (e.g., `+`)
2192
+ * `args` are the arguments of the operation.
2193
+ * `operation description` is an HDLRuby description of the new operation.
2197
2194
 
2198
- For example, for `fix32` a 32-bit (decimal point at 16-bit) fixed point type defined as follows:
2195
+ For example, for `fix32` a 32-bit (decimal point at 16-bit) fixed-point type defined as follows:
2199
2196
 
2200
2197
  ```ruby
2201
2198
  signed[31..0].typedef(:fix32)
@@ -2212,7 +2209,7 @@ end
2212
2209
  Please notice, that in the code above, the left value has been casted to a plain bit-vector in order to avoid infinite recursive call of the `*` operator.
2213
2210
 
2214
2211
  Operator can also be overloaded for generic types. However, is such a case, the generic argument must also be present in the list of arguments of the overloaded operators.
2215
- For instance, let us consider the following fixed point type of variable width (and whose decimal point is set at the half of its bit range):
2212
+ For instance, let us consider the following fixed-point type of variable width (and whose decimal point is set at the half of its bit range):
2216
2213
 
2217
2214
  ```ruby
2218
2215
  typedef(:fixed) do |width|
@@ -2280,7 +2277,7 @@ __Note__:
2280
2277
 
2281
2278
  Like with any Ruby program it is possible to define and execute methods anywhere in HDLRuby using the standard Ruby syntax. When defined, a method is attached to the enclosing HDLRuby construct. For instance, when defining a method when declaring a system, it will be usable within this system, while when defining a method outside any construct, it will be usable everywhere in the HDLRuby description.
2282
2279
 
2283
- A method can include HDLRuby code in which case the resulting hardware is appended to the current construct. For example the following code adds a connection between `sig0` and `sig1` in system `sys0`, and transmission between `sig0` and `sig1` in the behavior of `sys1`.
2280
+ A method can include HDLRuby code in which case the resulting hardware is appended to the current construct. For example, the following code adds a connection between `sig0` and `sig1` in system `sys0`, and transmission between `sig0` and `sig1` in the behavior of `sys1`.
2284
2281
 
2285
2282
  ```ruby
2286
2283
  def some_arrow
@@ -2308,7 +2305,7 @@ __Warning__:
2308
2305
 
2309
2306
  - In the above example, the semantic of `some_arrow` changes depending on where it is invoked from: within a system, it is a connection, within a behavior it is a transmission.
2310
2307
 
2311
- - Using Ruby methods for describing hardware might lead to weak code, for example the in following code, the method declares `in0` as input signal. Hence, while used in `sys0` no problems happens, an exception will be raised for `sys1` because a signal `in0` is already declare, and will also be raised for `sys2` because it is not possible to declare an input from within a behavior.
2308
+ - Using Ruby methods for describing hardware might lead to weak code, for example the in following code, the method declares `in0` as input signal. Hence, while used in `sys0` no problem happens, an exception will be raised for `sys1` because a signal `in0` is already declare, and will also be raised for `sys2` because it is not possible to declare an input from within a behavior.
2312
2309
 
2313
2310
  ```ruby
2314
2311
  def in_decl
@@ -2349,7 +2346,7 @@ end
2349
2346
  ```
2350
2347
 
2351
2348
 
2352
- While requiring care, properly designed method can be very useful for clean code reuse. For example the following method allows to start the execution of a block after a given number of cycles:
2349
+ While requiring care, properly designed method can be very useful for clean code reuse. For example, the following method allows to start the execution of a block after a given number of cycles:
2353
2350
 
2354
2351
  ```ruby
2355
2352
  def after(cycles,rst = $rst, &code)
@@ -2409,7 +2406,7 @@ Like any Ruby classes, the constructs of HDLRuby can be dynamically extended. If
2409
2406
 
2410
2407
  ### Extending HDLRuby constructs globally
2411
2408
 
2412
- By gobal extension of hardware constructs we actually mean the classical extension of Ruby classes by monkey patching the corresponding class. For example, it is possible to add a methods giving the number of signals in the interface of a system instance as follows:
2409
+ By global extension of hardware constructs, we mean the classical extension of Ruby classes by monkey patching the corresponding class. For example, it is possible to add a method giving the number of signals in the interface of a system instance as follows:
2413
2410
 
2414
2411
  ```ruby
2415
2412
  class SystemI
@@ -2498,7 +2495,7 @@ system :some_system, my_base do
2498
2495
  end
2499
2496
  ```
2500
2497
 
2501
- However, when generation the low-level description of this system, code similar to the following will have to be written for applying `my_generation`:
2498
+ However, when generation the low-level description of this system, code like the following will have to be written for applying `my_generation`:
2502
2499
 
2503
2500
  ```ruby
2504
2501
  some_system :instance0
@@ -2555,7 +2552,7 @@ include HDLRuby::High::Std
2555
2552
 
2556
2553
  The `clocks` library provides utilities for an easier handling of clock synchronizations.
2557
2554
 
2558
- It adds the possibility to multiply events by integer. The result is a new event whose frequency is divided by the integer multiplicand. For example the following code describes a D-FF that memorizes each three clock cycle.
2555
+ It adds the possibility to multiply events by integer. The result is a new event whose frequency is divided by the integer multiplicand. For example, the following code describes a D-FF that memorizes each three clock cycle.
2559
2556
 
2560
2557
  ```ruby
2561
2558
  require 'std/clocks'
@@ -2584,11 +2581,12 @@ after(<number>,<clock>,<reset>)
2584
2581
  ```
2585
2582
 
2586
2583
  Where:
2584
+
2587
2585
  * `<number>` is the number of cycles to wait.
2588
2586
  * `<clock>` is the clock to use, this argument can be omitted.
2589
2587
  * `<reset>` is the signal used to reset the counter used for waiting, this argument can be omitted.
2590
2588
 
2591
- This statement can be used both inside or outside a clocked behavior. When used within a clocked behavior, the clock event of the behavior is used for the counter unless specified otherwise. When used outside such a behavior, the clock is the global default clock `$clk`. In both cases, the reset is the global reset `$rst` unless specified otherwise.
2589
+ This statement can be used either inside or outside a clocked behavior. When used within a clocked behavior, the clock event of the behavior is used for the counter unless specified otherwise. When used outside such a behavior, the clock is the global default clock `$clk`. In both cases, the reset is the global reset `$rst` unless specified otherwise.
2592
2590
 
2593
2591
  The second construct is the `before` statement that activates a block until a given number of clocks cycles is passed. Its syntax and usage is identical to the `after` statement.
2594
2592
 
@@ -2663,7 +2661,7 @@ State transitions are by default set to be from one state to the following in th
2663
2661
  goto(<condition>,<names>)
2664
2662
  ```
2665
2663
 
2666
- Where `condition` is a signal whose value is used as index for selection the target state among the ones specified in the `names` list. For example the following statement indicate to go to state named `st_a` if the `cond` is 0, `st_b` if condition is 1 and `st_c` if condition is 2, otherwise this specific transition is ignored:
2664
+ Where `condition` is a signal whose value is used as index for selection the target state among the ones specified in the `names` list. For example, the following statement indicate to go to state named `st_a` if the `cond` is 0, `st_b` if condition is 1 and `st_c` if condition is 2, otherwise this specific transition is ignored:
2667
2665
 
2668
2666
  ```ruby
2669
2667
  goto(cond,:st_a,:st_b,:st_c)
@@ -2671,7 +2669,7 @@ goto(cond,:st_a,:st_b,:st_c)
2671
2669
 
2672
2670
  Several goto statements can be used, the last one having priority provided it is taken (i.e., its condition correspond to one of the target state). If no goto is taken, the next transition is the next declared one.
2673
2671
 
2674
- For example the following code describes a FSM describing a circuit that checks if two buttons (`but_a` and `but_b`) are pressed and released in sequence for activating an output signal (`ok`):
2672
+ For example, the following code describes a FSM describing a circuit that checks if two buttons (`but_a` and `but_b`) are pressed and released in sequence for activating an output signal (`ok`):
2675
2673
 
2676
2674
  ```ruby
2677
2675
  fsm(clk.posedge,rst,:sync) do
@@ -2698,19 +2696,16 @@ end
2698
2696
  ## Channel
2699
2697
  <a name="channel"></a>
2700
2698
 
2701
- This library provides a unified interface to complex communication protocols. It provides a new kind of component called the channel that abstracts the details of a communication protocol. The channels an be used similarly to the ports of a system and are used through a unified interface so that changing the kind of channel, i.e., the communication protocol, does not require any modification of the code.
2699
+ This library provides a unified interface to complex communication protocols through a new kind of components called the channels that abstract the details of communication protocols. The channels an be used similarly to the ports of a system and are used through a unified interface so that changing the kind of channel, i.e., the communication protocol, does not require any modification of the code.
2702
2700
 
2703
- A channel is used similarly to a pipe: it has an input where data can be written and an output where data can be read. The ordering of the data and the synchronisation depend on the internals of the channel, .e.g., a channel can be FIFO or LIFO. The interaction with the channel is done using the following methods:
2701
+ A channel is used similarly to a pipe: it has an input where data can be written and an output where data can be read. The ordering of the data and the synchronization depend on the internals of the channel, e.g., a channel can be FIFO or LIFO. The interaction with the channel is done using the following methods:
2704
2702
 
2705
2703
  * `writer_ports`: generate ports in the system for writing to the channel. This method is used without any argument.
2706
-
2707
2704
  * `reader_ports`: generate ports in the system for reading from the channel. This method is used without any argument.
2708
-
2709
2705
  * `write(<value>) <block>`: write `value` to the channel and execute `block` when `write` completes. Both `value` and `block` may be omitted depending on the kind of channel.
2710
-
2711
2706
  * `read(<target>) <block>`: read the channel, assign the result to signal `target` and execute `block` when the read completes. Both `target` and `block` may be omitted depending on the kind of channel.
2712
2707
 
2713
- For example a system sending successive 8 bit values through a channel can be described as follows:
2708
+ For example, a system sending successive 8-bit values through a channel can be described as follows:
2714
2709
 
2715
2710
  ```ruby
2716
2711
  system :producer8 do |channel|
@@ -2739,15 +2734,124 @@ A new channel is declared like using the keyword `channel` as follows:
2739
2734
  channel <name> <block>
2740
2735
  ```
2741
2736
 
2742
- Where `name` is the name of the channel and `block` is a procedure block describing the channel. This block can contain any HDLRuby code, and is actually similar to the content of a block describing a system with the difference that it does not have standard input, output and inout ports are declared differently and that it supports following additional keywords:
2737
+ Where `name` is the name of the channel and `block` is a procedure block describing the channel. This block can contain any HDLRuby code, and is comparable to the content of a block describing a system with the difference that it does not have standard input, output and inout ports are declared differently and that it supports following additional keywords:
2738
+
2739
+ * `reader_input <list of names>`: declares the input ports on the reader side. The list must give the names of the inner signals of the channel that can be read using the reader procedure.
2740
+ * `reader_output <list of names>`: declares the output ports on the reader side. The list must give the names of the inner signals of the channel that can be written using the reader procedure.
2741
+ * `writer_input <list of names>`: declares the inputs on the writer side. The list must give the names of the inner signals of the channel that can be read using the writer procedure.
2742
+ * `writer_output <lust of names>`: declares the outputs on the writer side. The list must give the names of the inner signals of the channel that can be written using the writer procedure.
2743
+ * `command <name> <block>`: declares a new command for the channel.
2744
+ * `reader <block>`: defines the reader's access procedure.
2745
+ This procedure is invoked by method `read` of the channel (please refer to the previous example).
2746
+ The block takes the following arguments:
2747
+ - `blk`: the block to execute when the read completes.
2748
+ - `target`: the signal where to put the read value.
2749
+ * `writer < block>`: defines the writer's access procedure.
2750
+ This procedure is invoked by method `write` of the channel (please refer to the previous example).
2751
+ The block takes the following arguments:
2752
+ - `blk`: the block to execute when the write completes.
2753
+ - `target`: the signal that contains the value to write.
2754
+
2755
+ For example, a channel implemented by a simple register of generic type `typ`, that can be set to 0 using the `reset` command can be described as follows:
2756
+
2757
+ ```ruby
2758
+ channel :regch do |typ|
2759
+ # The register.
2760
+ typ.inner :reg
2761
+
2762
+ # The reader procedure can read reg
2763
+ reader_input :reg
2764
+ # The writer procedure can write reg
2765
+ writer_output :reg
2766
+
2767
+ # Declares a reset
2768
+ command(:reset) { reg <= 0 }
2769
+
2770
+ # Defines the reader procedure.
2771
+ reader do |blk,target|
2772
+ target <= reg
2773
+ blk.call if blk
2774
+ end
2775
+
2776
+ # Defines the writer procedure.
2777
+ writer do |blk,target|
2778
+ reg <= target
2779
+ blk.call if blk
2780
+ end
2781
+ end
2782
+ ```
2783
+
2784
+ __Notes__:
2785
+
2786
+ * The described channel assumes that at the `write` method of the channel is invoked within a clocked process (otherwise, the register will become a latch).
2787
+ * The described channel supports the `read` and `write` methods to be invoked with or without a block.
2788
+
2789
+
2790
+ Like systems, a channel must be instantiated for being used, and the instantiation procedure is identical:
2791
+
2792
+ ```ruby
2793
+ <channel name> :<instance name>
2794
+ ```
2795
+
2796
+ And in case there are generic parameter, the instantiation procedure is as follows:
2797
+
2798
+ ```ruby
2799
+ <channel name>(:<instance name>).(<generic parameters>)
2800
+ ```
2801
+
2802
+ After a channel is instantiated, it must be linked to the circuits that will communicate through it. This is done when instantiating these circuits. If a circuit reads on the channel, it will be instantiated as follows:
2803
+
2804
+ ```ruby
2805
+ <system name>(<channel instance>).(:<instance name>).(<circuit standard connections>,*<channel instance>.reader_signals)
2806
+ ```
2807
+
2808
+ If the circuit writes on the channel, it has to be instantiated as follows:
2809
+
2810
+ ```ruby
2811
+ <system name>(<channel instance>).(:<instance name>).(<circuit standard connections>,*<channel instance>.writer_signals)
2812
+ ```
2813
+
2814
+ __Notes__:
2815
+
2816
+ * It is possible for a circuit to access several channels. For that purpose, each channel must be passed as generic arguments, and their corresponding `reader_signals` and `writer_signals` are to be put in the order of declaration.
2817
+ * It is also possible for a circuit to read and write on the same channel. For that purpose, the channel will be passed several times as generic arguments, and the corresponding `reader_signals` and `writer_signals` are to be put in the order of declaration.
2818
+
2819
+ The following code is an example instantiating the register channel presented above for connecting an instance of `producer8` and another circuit called `consumer8`:
2820
+
2821
+ ```ruby
2822
+ # System wrapping the producer and the consumer circuits.
2823
+ system :producer_consumer8 do
2824
+ # The clock and reset of the circuits
2825
+ input :clk, :rst
2826
+
2827
+ # Instance of the channel (using 8-bit data).
2828
+ regch([8]).(:regchI)
2829
+
2830
+ # Reset the channel on positive edges of signal rst.
2831
+ regchI.reset.at(rst.posedge)
2832
+
2833
+ # Instanciate the producer.
2834
+ producer8(regch).(:producerI).(clk,rst,*regch.writer_signals)
2835
+
2836
+ # Instanciate the consummer.
2837
+ consumer8(regch).(:consumerI).(clk.rst,*regch.reader_signals)
2838
+ end
2839
+ ```
2840
+
2841
+ __Note__:
2842
+
2843
+ * The code of the circuits, in the examples `producer8`, `consumer8` and `producer_consummer8` is independent of the content of the channel. For example, the sample `with_channel.rb` (please see [sample](#sample)) use the same circuits with a channel implementing a handshaking.
2743
2844
 
2744
- * srgg
2745
2845
 
2746
2846
  ## Reconf
2747
2847
  <a name="reconf"></a>
2748
2848
 
2749
- This library provides a unified interface to partially (or dynamically)
2750
- reconfigurable devices.
2849
+ This library provides a unified interface to partially (or dynamically) reconfigurable devices.
2850
+
2851
+ __Warning__:
2852
+
2853
+ While the framework of this library is completed, not target reconfigurable device is defined yet.
2854
+
2751
2855
 
2752
2856
  ## Pipeline
2753
2857
  <a name="pipeline"></a>
@@ -2755,17 +2859,39 @@ reconfigurable devices.
2755
2859
  This library provides a construct for an easy description of pipeline architectures.
2756
2860
 
2757
2861
 
2862
+ # Sample HDLRuby descriptions
2863
+ <a name="sample"></a>
2758
2864
 
2865
+ Several samples HDLRuby descriptions are available in the following directory:
2759
2866
 
2760
- # Development
2867
+ path/to/HDLRuby/lib/HDLRuby/hdr\_samples
2761
2868
 
2762
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
2869
+ For the gem install, the path to HDLRuby can be found using the following:
2870
+
2871
+ ```
2872
+ gem which HDLRuby
2873
+ ```
2874
+
2875
+ The naming convention of the samples is the following:
2876
+
2877
+ * `<name>.rb`: default type of sample.
2878
+ * `<name>_gen.rb`: generic parameters are required for processing the sample.
2879
+ * `<name>_bench.rb`: sample including a simulation benchmark, these are the only samples that can be simulated using `hdrcc -S`. Please notice that such sample cannot be converted to VHDL nor Verlog HDL yet.
2763
2880
 
2764
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
2765
2881
 
2766
2882
  # Contributing
2767
2883
 
2768
- Bug reports and pull requests are welcome on GitHub at https://github.com/Lovic Gauthier/HDLRuby.
2884
+ Bug reports and pull requests are welcome on GitHub at https://github.com/civol/HDLRuby.
2885
+
2886
+
2887
+ # To do
2888
+
2889
+ * Test the compatibility of the HDLRuby framework with the Microsoft Windows environments.
2890
+ * Add the generation of VHDL and Verilog code for the time behaviors.
2891
+ * Provide targets for the `Reconf` library.
2892
+ * Add a standard wave output for the simulator.
2893
+ * Find and fix the (maybe) terrifying amount of bugs.
2894
+ * Add a GUI (any volonteer to do it?).
2769
2895
 
2770
2896
 
2771
2897
  # License
@@ -1,3 +1,3 @@
1
1
  module HDLRuby
2
- VERSION = "2.0.9"
2
+ VERSION = "2.0.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.0.9
4
+ version: 2.0.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: 2019-12-27 00:00:00.000000000 Z
11
+ date: 2019-12-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -47,7 +47,8 @@ email:
47
47
  executables:
48
48
  - hdrcc
49
49
  extensions: []
50
- extra_rdoc_files: []
50
+ extra_rdoc_files:
51
+ - README.md
51
52
  files:
52
53
  - ".gitignore"
53
54
  - ".travis.yml"
@@ -274,7 +275,8 @@ files:
274
275
  homepage: https://github.com/civol
275
276
  licenses:
276
277
  - MIT
277
- metadata: {}
278
+ metadata:
279
+ source_code_uri: https://github.com/civol/HDLRuby
278
280
  post_install_message:
279
281
  rdoc_options: []
280
282
  require_paths: