HDLRuby 2.0.16 → 2.0.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +32 -32
- data/lib/HDLRuby/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 208d8d11461fecdbdb9417afde401104e33dc2b8
|
4
|
+
data.tar.gz: e9f56d18638dca030c07b3d7946f7027bfda7b4a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18cb219b24c63e5a905c9bb440dc1105b8d44249e6270bfa62a400928c70a025a6088c7ab23e7649b63c4de11d01800f301f67363bf193a4c0470ab8cd8fbe12
|
7
|
+
data.tar.gz: 9759ab1f2b43a3c1586504803178883356521322cba385a558d947196ac5a80a5be716613526fea3af249968c89eb8aa6f923ab8677fc7c81d65fd8a5eabb367
|
data/README.md
CHANGED
@@ -11,7 +11,7 @@ The recommended installation method is from rubygem as follows:
|
|
11
11
|
gem install HDLRuby
|
12
12
|
```
|
13
13
|
|
14
|
-
|
14
|
+
Developers willing to contribute to HDLRuby can install the sources from github as follows:
|
15
15
|
|
16
16
|
```
|
17
17
|
git clone HDLRuby
|
@@ -45,7 +45,7 @@ Where:
|
|
45
45
|
| Options | |
|
46
46
|
|:------------------|:-----------------------------------------------------|
|
47
47
|
| `-y, --yaml` | Output in YAML format |
|
48
|
-
| `-v, --verilog` | Output in
|
48
|
+
| `-v, --verilog` | Output in Verilog HDL format |
|
49
49
|
| `-V, --vhdl` | Output in VHDL format |
|
50
50
|
| `-s, --syntax` | Output the Ruby syntax tree |
|
51
51
|
| `-C, --clang` | Output the C code of the simulator |
|
@@ -82,7 +82,7 @@ hdrcc -v adder.rb adder
|
|
82
82
|
hdrcc -V -t adder --param 16 adder_gen.rb adder
|
83
83
|
```
|
84
84
|
|
85
|
-
* Compile system `multer` with inputs and output bit width is generic from `multer_gen.rb` input file to a 16x16->32
|
85
|
+
* Compile system `multer` with inputs and output bit width is generic from `multer_gen.rb` input file to a 16x16->32-bit circuit whose low-level YAML description into directory `multer`:
|
86
86
|
|
87
87
|
```
|
88
88
|
hdrcc -y -t multer -p 16,16,32 multer_gen.rb multer
|
@@ -156,7 +156,7 @@ adder = HDLRuby::from_yaml(File.read("#{$:[0]}/HDLRuby/low_samples/adder.yaml"))
|
|
156
156
|
|
157
157
|
__Note__:
|
158
158
|
|
159
|
-
- A `HDLRuby::Low` description of hardware can only be built through standard Ruby class constructors
|
159
|
+
- A `HDLRuby::Low` description of hardware can only be built through standard Ruby class constructors and does not include any validity check of the resulting hardware.
|
160
160
|
|
161
161
|
|
162
162
|
|
@@ -175,7 +175,7 @@ __Notes__:
|
|
175
175
|
## Introduction
|
176
176
|
|
177
177
|
This introduction gives a glimpse of the possibilities of the language.
|
178
|
-
However, we do recommend
|
178
|
+
However, we do recommend consulting the section about the [high-level programming features](#highfeat) to have a more complete view of the advanced possibilities of this language.
|
179
179
|
|
180
180
|
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:
|
181
181
|
|
@@ -192,7 +192,7 @@ end
|
|
192
192
|
|
193
193
|
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).
|
194
194
|
|
195
|
-
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:
|
195
|
+
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:
|
196
196
|
|
197
197
|
```ruby
|
198
198
|
dff :dff0
|
@@ -373,7 +373,7 @@ end
|
|
373
373
|
|
374
374
|
In this later case, only `dff0` will have an inverted output, the other instances of `dff` will not change.
|
375
375
|
|
376
|
-
Now assuming we opted for the first solution, we have now `dff_full`, a highly advanced D-FF with such unique features as an inverted output. So we would like to use it in other designs, for example a shift register of `n` bits. Such a system will include a generic number of `dff_full` instances, and can be
|
376
|
+
Now assuming we opted for the first solution, we have now `dff_full`, a highly advanced D-FF with such unique features as an inverted output. So, we would like to use it in other designs, for example a shift register of `n` bits. Such a system will include a generic number of `dff_full` instances, and can be
|
377
377
|
described as follows making use of the native Ruby method `each_cons` for connecting them together:
|
378
378
|
|
379
379
|
```ruby
|
@@ -451,7 +451,7 @@ In the code above, there are two generic parameters,
|
|
451
451
|
|
452
452
|
The description of the sum of product maybe more difficult to understand for people not familiar with the Ruby language. The `each_with_index` method iterates over the coefficients adding their index as iteration variable, the resulting operation (i.e., the iteration loop) is then modified by the `reduce` method that accumulates the code passed as arguments. This code, starting by `|sum,coef,i|` simply performs the addition of the current accumulation result (`sum`) with the product of the current coefficient (`coef`) and input (`ins[i]`, where `i` is the index) in the iteration. The argument `_0` initializes the sum to `0`.
|
453
453
|
|
454
|
-
While slightly longer than the previous description, this description allows to declare a circuit implementing a sum of product with any bit width and any number of coefficients. For instance, the following code describes a signed 32-bit sum of product with 16 coefficients (
|
454
|
+
While slightly longer than the previous description, this description allows to declare a circuit implementing a sum of product with any bit width and any number of coefficients. For instance, the following code describes a signed 32-bit sum of product with 16 coefficients (just random numbers here).
|
455
455
|
|
456
456
|
```ruby
|
457
457
|
sumprod(signed[32], [3,78,43,246, 3,67,1,8, 47,82,99,13, 5,77,2,4]).(:my_circuit)
|
@@ -559,7 +559,7 @@ sumprod(sat16_1000,
|
|
559
559
|
47,82,99,13, 5,77,2,4]).(:my_circuit)
|
560
560
|
```
|
561
561
|
|
562
|
-
It is also possible to declare a generic type. For instance a generic signed type with saturation can be declared as follows:
|
562
|
+
It is also possible to declare a generic type. For instance, a generic signed type with saturation can be declared as follows:
|
563
563
|
|
564
564
|
```ruby
|
565
565
|
typedef :sat do |width, max|
|
@@ -775,7 +775,7 @@ mem8_16I.clk <= clk
|
|
775
775
|
It is also possible to connect multiple signals of an instance using the call operator `.()` as follows, where each target can be any expression:
|
776
776
|
|
777
777
|
```ruby
|
778
|
-
<
|
778
|
+
<instance name>.(<signal name0>: <target0>, ...)
|
779
779
|
```
|
780
780
|
|
781
781
|
For example, the following code connects signals `clk` and `rst` of instance
|
@@ -1095,7 +1095,7 @@ Each behavior of a system is associated with a list of events, called sensibilit
|
|
1095
1095
|
|
1096
1096
|
There are three kinds of event: positive edge events represent the instants when their corresponding signals vary from 0 to 1, negative edge events
|
1097
1097
|
represent the instants when their corresponding signals vary from 1 to 0 and the change events represent the instants when their corresponding signals vary.
|
1098
|
-
Events are declared directly from the signals, using the `posedge` operator for positive edge, the `negedge` operator for negative edge, and the `change` operator for change. For example the following code declares 3 behaviors activated respectively on the positive edge, the negative edge and any change of the `clk` signal.
|
1098
|
+
Events are declared directly from the signals, using the `posedge` operator for positive edge, the `negedge` operator for negative edge, and the `change` operator for change. For example, the following code declares 3 behaviors activated respectively on the positive edge, the negative edge and any change of the `clk` signal.
|
1099
1099
|
|
1100
1100
|
```ruby
|
1101
1101
|
inner :clk
|
@@ -1221,7 +1221,7 @@ __Notes__:
|
|
1221
1221
|
## Types
|
1222
1222
|
<a name="types"></a>
|
1223
1223
|
|
1224
|
-
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
|
1224
|
+
Each signal and each expression is associated with a data type which describes the kind of value it can represent. In HDLRuby, the data types represent
|
1225
1225
|
bit vectors associated with the way they should be interpreted, i.e., as bit strings, unsigned values, signed values, or hierarchical contents.
|
1226
1226
|
|
1227
1227
|
### Type construction
|
@@ -1259,13 +1259,13 @@ A vector of multiple types, also called tuple, is declared as follows:
|
|
1259
1259
|
[<type 0>, <type 1>, ... ]
|
1260
1260
|
```
|
1261
1261
|
|
1262
|
-
For example, the following code declares the type of the vectors made of
|
1262
|
+
For example, the following code declares the type of the vectors made of an 8-bit logical, a 16-bit signed and a 16-bit unsigned values:
|
1263
1263
|
|
1264
1264
|
```ruby
|
1265
1265
|
[ bit[8], signed[16], unsigned[16] ]
|
1266
1266
|
```
|
1267
1267
|
|
1268
|
-
__The structure
|
1268
|
+
__The structure operator__ `{}` is used for building hierarchical types made of named subtypes. This operator is used as follows:
|
1269
1269
|
|
1270
1270
|
```ruby
|
1271
1271
|
{ <name 0>: <type 0>, <name 1>: <type 1>, ... }
|
@@ -1286,7 +1286,7 @@ It is possible to give names to type constructs using the `typedef` keywords as
|
|
1286
1286
|
<type construct>.typedef :<name>
|
1287
1287
|
```
|
1288
1288
|
|
1289
|
-
For example, the
|
1289
|
+
For example, the following gives the name `char` to a signed 8-bit vector:
|
1290
1290
|
|
1291
1291
|
```ruby
|
1292
1292
|
signed[7..0].typedef :char
|
@@ -1518,7 +1518,7 @@ The arithmetic operators can only be used on vectors of `bit`, `unsigned` or `si
|
|
1518
1518
|
<a name="comparison"></a>
|
1519
1519
|
|
1520
1520
|
Comparison operators are the operators whose result is either true or false.
|
1521
|
-
In HDLRuby, true and false are represented by respectively `bit` value 1 and `bit` value 0.
|
1521
|
+
In HDLRuby, true and false are represented by respectively `bit` value 1 and `bit` value 0. These operators are `==`, `!=`, `<`, `>`, `<=`, `>=` . They
|
1522
1522
|
have the same meaning as their Ruby equivalents.
|
1523
1523
|
|
1524
1524
|
__Notes__:
|
@@ -1531,7 +1531,7 @@ __Notes__:
|
|
1531
1531
|
#### Logic and shift operators
|
1532
1532
|
<a name="logic"></a>
|
1533
1533
|
|
1534
|
-
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.
|
1534
|
+
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.
|
1535
1535
|
|
1536
1536
|
__Note__: there is two reasons why there is no Boolean operators
|
1537
1537
|
|
@@ -1851,10 +1851,10 @@ timed do
|
|
1851
1851
|
end
|
1852
1852
|
```
|
1853
1853
|
|
1854
|
-
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.
|
1854
|
+
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.
|
1855
1855
|
There are two kinds of such statements:
|
1856
1856
|
|
1857
|
-
- 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:
|
1857
|
+
- 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:
|
1858
1858
|
|
1859
1859
|
```ruby
|
1860
1860
|
wait(10.ns)
|
@@ -2151,7 +2151,7 @@ It is possible to pursue the definition of a system after it has been declared u
|
|
2151
2151
|
end
|
2152
2152
|
```
|
2153
2153
|
|
2154
|
-
For example `dff`, a system describing a D-FF, can be modified to have an inverted output as follows:
|
2154
|
+
For example, `dff`, a system describing a D-FF, can be modified to have an inverted output as follows:
|
2155
2155
|
|
2156
2156
|
```ruby
|
2157
2157
|
dff.open do
|
@@ -2320,7 +2320,7 @@ __Warning__:
|
|
2320
2320
|
|
2321
2321
|
- 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.
|
2322
2322
|
|
2323
|
-
- 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
|
2323
|
+
- 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 declared and will also be raised for `sys2` because it is not possible to declare an input from within a behavior.
|
2324
2324
|
|
2325
2325
|
```ruby
|
2326
2326
|
def in_decl
|
@@ -2567,7 +2567,7 @@ include HDLRuby::High::Std
|
|
2567
2567
|
|
2568
2568
|
The `clocks` library provides utilities for an easier handling of clock synchronizations.
|
2569
2569
|
|
2570
|
-
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
|
2570
|
+
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 cycles.
|
2571
2571
|
|
2572
2572
|
```ruby
|
2573
2573
|
require 'std/clocks'
|
@@ -2603,7 +2603,7 @@ Where:
|
|
2603
2603
|
|
2604
2604
|
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.
|
2605
2605
|
|
2606
|
-
The second construct is the `before` statement that activates a block until a given number of clocks cycles is passed. Its syntax and usage
|
2606
|
+
The second construct is the `before` statement that activates a block until a given number of clocks cycles is passed. Its syntax and usage are identical to the `after` statement.
|
2607
2607
|
|
2608
2608
|
|
2609
2609
|
## Decoder
|
@@ -2657,7 +2657,7 @@ The states of a FSM are described follows:
|
|
2657
2657
|
|
2658
2658
|
Where `kind` is the kind of state, `name` is the name of the state, and `block` is the actions to execute for the corresponding state. The kinds of states are the followings:
|
2659
2659
|
|
2660
|
-
* reset: the state reached when resetting the FSM. This state can be forced to be asynchronous by setting the `name` argument to `:async` and forced to be synchronous by setting the `name` argument to `:sync`. By default the `name` argument is to be omitted.
|
2660
|
+
* reset: the state reached when resetting the FSM. This state can be forced to be asynchronous by setting the `name` argument to `:async` and forced to be synchronous by setting the `name` argument to `:sync`. By default, the `name` argument is to be omitted.
|
2661
2661
|
* state: the default kind of state, it will be synchronous if the FSM is synchronous or asynchronous otherwise.
|
2662
2662
|
* sync: the synchronous kind of state, it will be synchronous whatever the kind of FSM is used.
|
2663
2663
|
* async: the asynchronous kind of state, it will be asynchronous whatever the kind of FSM is used.
|
@@ -2711,7 +2711,7 @@ end
|
|
2711
2711
|
## Channel
|
2712
2712
|
<a name="channel"></a>
|
2713
2713
|
|
2714
|
-
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
|
2714
|
+
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 can 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.
|
2715
2715
|
|
2716
2716
|
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:
|
2717
2717
|
|
@@ -2754,7 +2754,7 @@ Where `name` is the name of the channel and `block` is a procedure block describ
|
|
2754
2754
|
* `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.
|
2755
2755
|
* `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.
|
2756
2756
|
* `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.
|
2757
|
-
* `writer_output <
|
2757
|
+
* `writer_output <list 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.
|
2758
2758
|
* `command <name> <block>`: declares a new command for the channel.
|
2759
2759
|
* `reader <block>`: defines the reader's access procedure.
|
2760
2760
|
This procedure is invoked by method `read` of the channel (please refer to the previous example).
|
@@ -2820,7 +2820,7 @@ After a channel is instantiated, it must be linked to the circuits that will com
|
|
2820
2820
|
<system name>(<channel instance>).(:<instance name>).(<circuit standard connections>,*<channel instance>.reader_signals)
|
2821
2821
|
```
|
2822
2822
|
|
2823
|
-
If the circuit writes on the channel, it
|
2823
|
+
If the circuit writes on the channel, it must be instantiated as follows:
|
2824
2824
|
|
2825
2825
|
```ruby
|
2826
2826
|
<system name>(<channel instance>).(:<instance name>).(<circuit standard connections>,*<channel instance>.writer_signals)
|
@@ -2845,10 +2845,10 @@ system :producer_consumer8 do
|
|
2845
2845
|
# Reset the channel on positive edges of signal rst.
|
2846
2846
|
regchI.reset.at(rst.posedge)
|
2847
2847
|
|
2848
|
-
#
|
2848
|
+
# Instantiate the producer.
|
2849
2849
|
producer8(regch).(:producerI).(clk,rst,*regch.writer_signals)
|
2850
2850
|
|
2851
|
-
#
|
2851
|
+
# Instantiate the consumer.
|
2852
2852
|
consumer8(regch).(:consumerI).(clk.rst,*regch.reader_signals)
|
2853
2853
|
end
|
2854
2854
|
```
|
@@ -2891,7 +2891,7 @@ The naming convention of the samples is the following:
|
|
2891
2891
|
|
2892
2892
|
* `<name>.rb`: default type of sample.
|
2893
2893
|
* `<name>_gen.rb`: generic parameters are required for processing the sample.
|
2894
|
-
* `<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
|
2894
|
+
* `<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 Verilog HDL yet.
|
2895
2895
|
|
2896
2896
|
|
2897
2897
|
# Contributing
|
@@ -2905,8 +2905,8 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/civol/
|
|
2905
2905
|
* Add the generation of VHDL and Verilog code for the time behaviors.
|
2906
2906
|
* Provide targets for the `Reconf` library.
|
2907
2907
|
* Add a standard wave output for the simulator.
|
2908
|
-
* Find and fix the (maybe) terrifying
|
2909
|
-
* Add a GUI (any
|
2908
|
+
* Find and fix the (maybe) terrifying number of bugs.
|
2909
|
+
* Add a GUI (any volunteer to do it?).
|
2910
2910
|
|
2911
2911
|
|
2912
2912
|
# License
|
data/lib/HDLRuby/version.rb
CHANGED