HDLRuby 3.9.5 → 3.9.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +26 -2
- data/ext/hruby_sim/hruby_rcsim_build.c +23 -0
- data/ext/hruby_sim/hruby_sim.h +29 -1
- data/ext/hruby_sim/hruby_sim_calc.c +141 -18
- data/ext/hruby_sim/hruby_sim_tree_calc.c +37 -0
- data/lib/HDLRuby/hdr_samples/case_bench.rb +1 -1
- data/lib/HDLRuby/hdr_samples/logic_bench.rb +12 -12
- data/lib/HDLRuby/hdr_samples/with_assign_to_slice.rb +19 -0
- data/lib/HDLRuby/hdr_samples/with_casez.rb +35 -0
- data/lib/HDLRuby/hdr_samples/with_henumerable.rb +1 -1
- data/lib/HDLRuby/hruby_high.rb +121 -12
- data/lib/HDLRuby/hruby_low.rb +50 -46
- data/lib/HDLRuby/hruby_rcsim.rb +7 -2
- data/lib/HDLRuby/hruby_verilog.rb +17 -6
- data/lib/HDLRuby/std/decoder.rb +2 -2
- data/lib/HDLRuby/verilog_hruby.rb +30 -0
- data/lib/HDLRuby/verilog_parser.rb +1 -1
- data/lib/HDLRuby/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 00a784914e79391b0aa065086641989892907de384b64b3b43b221587076fcf4
|
|
4
|
+
data.tar.gz: b53f9aa4f668cd8a736f476b4c8b86572ec8572f00f09ba85bfd484e67ff3fc6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0e35ec948e04837424e7a2992a9f06aa15d580305c68688bdf22270b73b762f759bb7c76785f3866dd2abc25a1eaf6835005e622467458e2b9ad04134839ab62
|
|
7
|
+
data.tar.gz: 3a3a557df353dff6b0203dcbc28fc3231d76fd6a7b7b29853061ac5451dc9a375f272f46adbb8b9ad4a838992f27097c443f0817c19d565103c2ffb0a0d343bf
|
data/README.md
CHANGED
|
@@ -475,7 +475,7 @@ These include:
|
|
|
475
475
|
|
|
476
476
|
* `hif` / `helsif` / `helse` for `if`-like conditionals
|
|
477
477
|
|
|
478
|
-
* `hcase` / `hwhen` / `helse` for `case`-like conditionals
|
|
478
|
+
* `hcase` / `hcasez` / `hwhen` / `helse` for `case`-like conditionals
|
|
479
479
|
|
|
480
480
|
* `mux`, an expression-level construct for multiplexers, which supports multiple inputs, unlike the ?: ternary operator in Verilog, which only handles two
|
|
481
481
|
|
|
@@ -1793,7 +1793,7 @@ The behavior of an assignment statement depends on the execution mode of the enc
|
|
|
1793
1793
|
|
|
1794
1794
|
### Control Statements
|
|
1795
1795
|
|
|
1796
|
-
There are two types of control statements in HDLRuby: the hardware if (`hif`) and the hardware case (`
|
|
1796
|
+
There are two types of control statements in HDLRuby: the hardware if (`hif`) the hardware case (`hcase`), and the hardware case with wildcards (`hcasez`).
|
|
1797
1797
|
|
|
1798
1798
|
#### hif
|
|
1799
1799
|
|
|
@@ -1820,6 +1820,30 @@ end
|
|
|
1820
1820
|
...
|
|
1821
1821
|
```
|
|
1822
1822
|
|
|
1823
|
+
#### hcasez
|
|
1824
|
+
|
|
1825
|
+
The `hcasez` construct consists of an expression and a list of value-block pairs. A block is executed when its corresponding value matches the value of the `hcasez` expression. If the value contains wildcard digits represented by a `z` they match any corresponding digit. It is declared as follows:
|
|
1826
|
+
|
|
1827
|
+
```ruby
|
|
1828
|
+
hcasez <expression>
|
|
1829
|
+
hwhen <value 0> do
|
|
1830
|
+
<block contents 0>
|
|
1831
|
+
end
|
|
1832
|
+
hwhen <value 1> do
|
|
1833
|
+
<block contents 1>
|
|
1834
|
+
end
|
|
1835
|
+
...
|
|
1836
|
+
```
|
|
1837
|
+
|
|
1838
|
+
As an example of wildcard, the following statement will be executed if val is equal to 5 or 7:
|
|
1839
|
+
|
|
1840
|
+
```ruby
|
|
1841
|
+
hcasez val
|
|
1842
|
+
hwhen _b01z1 do
|
|
1843
|
+
<block contents 0>
|
|
1844
|
+
end
|
|
1845
|
+
```
|
|
1846
|
+
|
|
1823
1847
|
#### helse
|
|
1824
1848
|
|
|
1825
1849
|
You can add a block that is executed when the condition of an `hif` is not met, or when no case in an hcase matches, using the `helse` keyword:
|
|
@@ -659,6 +659,28 @@ VALUE rcsim_make_hcase(VALUE mod, VALUE valueV, VALUE defoltV) {
|
|
|
659
659
|
return res;
|
|
660
660
|
}
|
|
661
661
|
|
|
662
|
+
/* Creating a hardware casez C object. */
|
|
663
|
+
VALUE rcsim_make_hcasez(VALUE mod, VALUE valueV, VALUE defoltV) {
|
|
664
|
+
// printf("rcsim_make_hcasez\n");
|
|
665
|
+
/* Allocates the hardware case. */
|
|
666
|
+
HCaseZ hcasez = (HCaseZ)malloc(sizeof(HCaseZS));
|
|
667
|
+
// printf("hcasez=%p\n",hcasez);
|
|
668
|
+
/* Set it up. */
|
|
669
|
+
hcasez->kind = HCASEZ;
|
|
670
|
+
hcasez->owner = NULL;
|
|
671
|
+
value_to_rcsim(ExpressionS,valueV,hcasez->value);
|
|
672
|
+
hcasez->num_whens = 0;
|
|
673
|
+
hcasez->matches = NULL;
|
|
674
|
+
hcasez->stmnts = NULL;
|
|
675
|
+
if (TYPE(defoltV) == T_NIL)
|
|
676
|
+
hcasez->defolt = NULL;
|
|
677
|
+
else
|
|
678
|
+
value_to_rcsim(StatementS,defoltV,hcasez->defolt);
|
|
679
|
+
/* Returns the C hardware case embedded into a ruby VALUE. */
|
|
680
|
+
VALUE res;
|
|
681
|
+
rcsim_to_value(HCaseZS,hcasez,res);
|
|
682
|
+
return res;
|
|
683
|
+
}
|
|
662
684
|
|
|
663
685
|
/* Creating a block C object. */
|
|
664
686
|
VALUE rcsim_make_block(VALUE mod, VALUE modeV) {
|
|
@@ -1927,6 +1949,7 @@ void Init_hruby_sim() {
|
|
|
1927
1949
|
rb_define_singleton_method(mod,"rcsim_make_timeTerminate",rcsim_make_timeTerminate,0);
|
|
1928
1950
|
rb_define_singleton_method(mod,"rcsim_make_hif",rcsim_make_hif,3);
|
|
1929
1951
|
rb_define_singleton_method(mod,"rcsim_make_hcase",rcsim_make_hcase,2);
|
|
1952
|
+
rb_define_singleton_method(mod,"rcsim_make_hcasez",rcsim_make_hcasez,2);
|
|
1930
1953
|
rb_define_singleton_method(mod,"rcsim_make_block",rcsim_make_block,1);
|
|
1931
1954
|
rb_define_singleton_method(mod,"rcsim_make_value_numeric",rcsim_make_value_numeric,2);
|
|
1932
1955
|
rb_define_singleton_method(mod,"rcsim_make_value_numeric_63one",rcsim_make_value_numeric_63one,2);
|
data/ext/hruby_sim/hruby_sim.h
CHANGED
|
@@ -27,6 +27,7 @@ typedef struct TransmitS_ TransmitS;
|
|
|
27
27
|
typedef struct PrintS_ PrintS;
|
|
28
28
|
typedef struct HIfS_ HIfS;
|
|
29
29
|
typedef struct HCaseS_ HCaseS;
|
|
30
|
+
typedef struct HCaseZS_ HCaseZS;
|
|
30
31
|
typedef struct TimeWaitS_ TimeWaitS;
|
|
31
32
|
typedef struct TimeRepeatS_ TimeRepeatS;
|
|
32
33
|
typedef struct TimeTerminateS_ TimeTerminateS;
|
|
@@ -63,6 +64,7 @@ typedef struct TransmitS_* Transmit;
|
|
|
63
64
|
typedef struct PrintS_* Print;
|
|
64
65
|
typedef struct HIfS_* HIf;
|
|
65
66
|
typedef struct HCaseS_* HCase;
|
|
67
|
+
typedef struct HCaseZS_* HCaseZ;
|
|
66
68
|
typedef struct TimeWaitS_* TimeWait;
|
|
67
69
|
typedef struct TimeRepeatS_* TimeRepeat;
|
|
68
70
|
typedef struct TimeTerminateS_* TimeTerminate;
|
|
@@ -91,7 +93,7 @@ typedef enum {
|
|
|
91
93
|
#endif
|
|
92
94
|
OBJECT, SYSTEMT, SIGNALI, SCOPE, BEHAVIOR, SYSTEMI, CODE, BLOCK, EVENT,
|
|
93
95
|
#ifdef RCSIM
|
|
94
|
-
/* Statements */ TRANSMIT, PRINT, HIF, HCASE,
|
|
96
|
+
/* Statements */ TRANSMIT, PRINT, HIF, HCASE, HCASEZ,
|
|
95
97
|
TIME_WAIT, TIME_REPEAT, TIME_TERMINATE,
|
|
96
98
|
/* Expressions */ UNARY, BINARY, SELECT, CONCAT, CAST,
|
|
97
99
|
/* References */ REF_OBJECT, REF_INDEX, REF_RANGE, REF_CONCAT,
|
|
@@ -300,6 +302,13 @@ Value shift_right_value(Value src0, Value src1, Value dst);
|
|
|
300
302
|
* @return dst */
|
|
301
303
|
extern Value equal_value(Value src0, Value src1, Value dst);
|
|
302
304
|
|
|
305
|
+
/** Computes the equal (NXOR) of two values treating Z as wildcards.
|
|
306
|
+
* @param src0 the first source value of the comparison
|
|
307
|
+
* @param src1 the second source value of the comparison
|
|
308
|
+
* @param dst the destination value
|
|
309
|
+
* @return dst */
|
|
310
|
+
extern Value equal_value_z(Value src0, Value src1, Value dst);
|
|
311
|
+
|
|
303
312
|
/** Computes the C equal of two general values.
|
|
304
313
|
* @param src0 the first source value of the addition
|
|
305
314
|
* @param src1 the second source value of the addition
|
|
@@ -307,6 +316,13 @@ extern Value equal_value(Value src0, Value src1, Value dst);
|
|
|
307
316
|
* @return the destination value */
|
|
308
317
|
extern Value equal_value_c(Value src0, Value src1, Value dst);
|
|
309
318
|
|
|
319
|
+
/** Computes the C equal of two general values treating Z as wildcards.
|
|
320
|
+
* @param src0 the first source value of the addition
|
|
321
|
+
* @param src1 the second source value of the addition
|
|
322
|
+
* @param dst the destination value
|
|
323
|
+
* @return the destination value */
|
|
324
|
+
extern Value equal_value_z_c(Value src0, Value src1, Value dst);
|
|
325
|
+
|
|
310
326
|
/** Computes the C not equal of two general values.
|
|
311
327
|
* @param src0 the first source value of the addition
|
|
312
328
|
* @param src1 the second source value of the addition
|
|
@@ -701,6 +717,18 @@ typedef struct HCaseS_ {
|
|
|
701
717
|
Statement defolt; /* The default statement. */
|
|
702
718
|
} HCaseS;
|
|
703
719
|
|
|
720
|
+
/** The C model of a hardware casez statement. */
|
|
721
|
+
typedef struct HCaseZS_ {
|
|
722
|
+
Kind kind; /* The kind of object. */
|
|
723
|
+
Object owner; /* The owner of the object if any. */
|
|
724
|
+
|
|
725
|
+
Expression value; /* The value to match. */
|
|
726
|
+
int num_whens; /* The number of possible cases. */
|
|
727
|
+
Expression* matches;/* The cases matching values. */
|
|
728
|
+
Statement* stmnts; /* The corresponding statements. */
|
|
729
|
+
Statement defolt; /* The default statement. */
|
|
730
|
+
} HCaseZS;
|
|
731
|
+
|
|
704
732
|
/** The C model of a time wait statement. */
|
|
705
733
|
typedef struct TimeWaitS_ {
|
|
706
734
|
Kind kind; /* The kind of object. */
|
|
@@ -1733,44 +1733,44 @@ static Value shift_right_value_bitstring(Value src0, Value src1, Value dst) {
|
|
|
1733
1733
|
}
|
|
1734
1734
|
|
|
1735
1735
|
|
|
1736
|
-
/**
|
|
1736
|
+
/** computes the equal (!xor) of two bitstring values.
|
|
1737
1737
|
* @param src0 the first source value of the and
|
|
1738
1738
|
* @param src1 the second source value of the and
|
|
1739
1739
|
* @param dst the destination value
|
|
1740
1740
|
* @return dst */
|
|
1741
1741
|
static Value equal_value_bitstring(Value src0, Value src1, Value dst) {
|
|
1742
1742
|
// printf("equal_value_bitstring.\n");
|
|
1743
|
-
/*
|
|
1743
|
+
/* compute the width of sources in bits. */
|
|
1744
1744
|
unsigned long long width0 = type_width(src0->type);
|
|
1745
1745
|
unsigned long long width1 = type_width(src1->type);
|
|
1746
1746
|
|
|
1747
|
-
/*
|
|
1747
|
+
/* update the destination capacity if required. */
|
|
1748
1748
|
resize_value(dst,width0);
|
|
1749
|
-
/*
|
|
1749
|
+
/* set the type and size of the destination from the type of the source.*/
|
|
1750
1750
|
dst->type = src0->type;
|
|
1751
1751
|
dst->numeric = 0;
|
|
1752
1752
|
|
|
1753
|
-
/*
|
|
1753
|
+
/* get access to the data of the sources. */
|
|
1754
1754
|
char *src0_data = src0->data_str;
|
|
1755
1755
|
char *src1_data = src1->data_str;
|
|
1756
|
-
/*
|
|
1756
|
+
/* get access to the data of the destination. */
|
|
1757
1757
|
char *dst_data = dst->data_str;
|
|
1758
1758
|
|
|
1759
|
-
/*
|
|
1759
|
+
/* get the sign extension character of source 1 and convert it to a bit.*/
|
|
1760
1760
|
int ext = bitstring_ext(src1);
|
|
1761
1761
|
|
|
1762
|
-
/*
|
|
1762
|
+
/* perform the !xor. */
|
|
1763
1763
|
unsigned long long count;
|
|
1764
|
-
/*
|
|
1764
|
+
/* check if values are the same. */
|
|
1765
1765
|
char same = '1';
|
|
1766
1766
|
for(count = 0; count < width0; ++count) {
|
|
1767
|
-
char d0 = src0_data[count] - '0'; /*
|
|
1767
|
+
char d0 = src0_data[count] - '0'; /* get and convert to bit. */
|
|
1768
1768
|
char d1;
|
|
1769
1769
|
if (count < width1) {
|
|
1770
|
-
/*
|
|
1771
|
-
d1 = src1_data[count] - '0';/*
|
|
1770
|
+
/* still within source 1. */
|
|
1771
|
+
d1 = src1_data[count] - '0';/* get and convert to bit. */
|
|
1772
1772
|
} else {
|
|
1773
|
-
/*
|
|
1773
|
+
/* outside source 1, use the sign extension. */
|
|
1774
1774
|
d1 = ext;
|
|
1775
1775
|
}
|
|
1776
1776
|
if (d0 == (d0&1)) {
|
|
@@ -1782,22 +1782,98 @@ static Value equal_value_bitstring(Value src0, Value src1, Value dst) {
|
|
|
1782
1782
|
break;
|
|
1783
1783
|
}
|
|
1784
1784
|
} else {
|
|
1785
|
-
/*
|
|
1785
|
+
/* undefined. */
|
|
1786
1786
|
same = 'x';
|
|
1787
1787
|
break;
|
|
1788
1788
|
}
|
|
1789
1789
|
} else {
|
|
1790
|
-
/*
|
|
1790
|
+
/* undefined. */
|
|
1791
1791
|
same = 'x';
|
|
1792
1792
|
break;
|
|
1793
1793
|
}
|
|
1794
1794
|
}
|
|
1795
|
-
/*
|
|
1795
|
+
/* set the destination to 0 or 1 depending of different. */
|
|
1796
1796
|
dst_data[0] = same;
|
|
1797
1797
|
for(count = 1; count < width0; ++count) {
|
|
1798
1798
|
dst_data[count] = '0';
|
|
1799
1799
|
}
|
|
1800
|
-
/*
|
|
1800
|
+
/* return the destination. */
|
|
1801
|
+
return dst;
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
/** computes the equal (!xor) of two bitstring values treating Z as wildcard.
|
|
1805
|
+
* @param src0 the first source value of the and
|
|
1806
|
+
* @param src1 the second source value of the and
|
|
1807
|
+
* @param dst the destination value
|
|
1808
|
+
* @return dst */
|
|
1809
|
+
static Value equal_value_z_bitstring(Value src0, Value src1, Value dst) {
|
|
1810
|
+
// printf("equal_value_bitstring.\n");
|
|
1811
|
+
/* compute the width of sources in bits. */
|
|
1812
|
+
unsigned long long width0 = type_width(src0->type);
|
|
1813
|
+
unsigned long long width1 = type_width(src1->type);
|
|
1814
|
+
|
|
1815
|
+
/* update the destination capacity if required. */
|
|
1816
|
+
resize_value(dst,width0);
|
|
1817
|
+
/* set the type and size of the destination from the type of the source.*/
|
|
1818
|
+
dst->type = src0->type;
|
|
1819
|
+
dst->numeric = 0;
|
|
1820
|
+
|
|
1821
|
+
/* get access to the data of the sources. */
|
|
1822
|
+
char *src0_data = src0->data_str;
|
|
1823
|
+
char *src1_data = src1->data_str;
|
|
1824
|
+
/* get access to the data of the destination. */
|
|
1825
|
+
char *dst_data = dst->data_str;
|
|
1826
|
+
|
|
1827
|
+
/* get the sign extension character of source 1 and convert it to a bit.*/
|
|
1828
|
+
int ext = bitstring_ext(src1);
|
|
1829
|
+
|
|
1830
|
+
/* perform the !xor. */
|
|
1831
|
+
unsigned long long count;
|
|
1832
|
+
/* check if values are the same. */
|
|
1833
|
+
char same = '1';
|
|
1834
|
+
for(count = 0; count < width0; ++count) {
|
|
1835
|
+
char d0 = src0_data[count] - '0'; /* get and convert to bit. */
|
|
1836
|
+
char d1;
|
|
1837
|
+
if (d0 == 'z' - '0' || d0 == 'Z' - '0') {
|
|
1838
|
+
/* Z is wildcard, so same. */
|
|
1839
|
+
continue;
|
|
1840
|
+
}
|
|
1841
|
+
if (count < width1) {
|
|
1842
|
+
/* still within source 1. */
|
|
1843
|
+
d1 = src1_data[count] - '0';/* get and convert to bit. */
|
|
1844
|
+
} else {
|
|
1845
|
+
/* outside source 1, use the sign extension. */
|
|
1846
|
+
d1 = ext;
|
|
1847
|
+
}
|
|
1848
|
+
if (d1 == 'z' - '0' || d1 == 'Z' - '0') {
|
|
1849
|
+
/* Z is wildcard, so same. */
|
|
1850
|
+
continue;
|
|
1851
|
+
}
|
|
1852
|
+
if (d0 == (d0&1)) {
|
|
1853
|
+
/* d0 is defined. */
|
|
1854
|
+
if (d1 == (d1&1)) {
|
|
1855
|
+
/* d1 is also defined. */
|
|
1856
|
+
if (d0 != d1) {
|
|
1857
|
+
same = '0';
|
|
1858
|
+
break;
|
|
1859
|
+
}
|
|
1860
|
+
} else {
|
|
1861
|
+
/* undefined. */
|
|
1862
|
+
same = 'x';
|
|
1863
|
+
break;
|
|
1864
|
+
}
|
|
1865
|
+
} else {
|
|
1866
|
+
/* undefined. */
|
|
1867
|
+
same = 'x';
|
|
1868
|
+
break;
|
|
1869
|
+
}
|
|
1870
|
+
}
|
|
1871
|
+
/* set the destination to 0 or 1 depending of different. */
|
|
1872
|
+
dst_data[0] = same;
|
|
1873
|
+
for(count = 1; count < width0; ++count) {
|
|
1874
|
+
dst_data[count] = '0';
|
|
1875
|
+
}
|
|
1876
|
+
/* return the destination. */
|
|
1801
1877
|
return dst;
|
|
1802
1878
|
}
|
|
1803
1879
|
|
|
@@ -3299,7 +3375,7 @@ Value shift_right_value(Value src0, Value src1, Value dst) {
|
|
|
3299
3375
|
}
|
|
3300
3376
|
|
|
3301
3377
|
|
|
3302
|
-
/** Computes the equal (
|
|
3378
|
+
/** Computes the equal (NXOR) of two general values.
|
|
3303
3379
|
* @param src0 the first source value of the addition
|
|
3304
3380
|
* @param src1 the second source value of the addition
|
|
3305
3381
|
* @param dst the destination value
|
|
@@ -3336,6 +3412,43 @@ Value equal_value(Value src0, Value src1, Value dst) {
|
|
|
3336
3412
|
return dst;
|
|
3337
3413
|
}
|
|
3338
3414
|
|
|
3415
|
+
/** Computes the equal (NXOR) of two general values.
|
|
3416
|
+
* @param src0 the first source value of the addition
|
|
3417
|
+
* @param src1 the second source value of the addition
|
|
3418
|
+
* @param dst the destination value
|
|
3419
|
+
* @return the destination value */
|
|
3420
|
+
Value equal_value_z(Value src0, Value src1, Value dst) {
|
|
3421
|
+
// printf("equal_value.\n");
|
|
3422
|
+
/* Might allocate a new value so save the current pool state. */
|
|
3423
|
+
unsigned int pos = get_value_pos();
|
|
3424
|
+
/* Do a numeric computation if possible, otherwise fallback to bitstring
|
|
3425
|
+
* computation. */
|
|
3426
|
+
if (src0->numeric) {
|
|
3427
|
+
if (src1->numeric) {
|
|
3428
|
+
// printf("numeric numeric\n");
|
|
3429
|
+
/* Both sources are numeric. */
|
|
3430
|
+
return equal_value_numeric(src0,src1,dst);
|
|
3431
|
+
} else {
|
|
3432
|
+
// printf("numeric bitstring\n");
|
|
3433
|
+
/* src1 is not numeric, convert src0 to bitstring. */
|
|
3434
|
+
src0 = set_bitstring_value(src0,get_value());
|
|
3435
|
+
}
|
|
3436
|
+
} else {
|
|
3437
|
+
/* src0 is not numeric, what about src1. */
|
|
3438
|
+
if (src1->numeric) {
|
|
3439
|
+
// printf("bitstring numeric\n");
|
|
3440
|
+
/* src1 is numeric, convert it to bitstring. */
|
|
3441
|
+
src1 = set_bitstring_value(src1,get_value());
|
|
3442
|
+
}
|
|
3443
|
+
}
|
|
3444
|
+
/* The sources cannot be numeric, compute bitsitrings. */
|
|
3445
|
+
dst = equal_value_z_bitstring(src0,src1,dst);
|
|
3446
|
+
/* Restores the pool of values. */
|
|
3447
|
+
set_value_pos(pos);
|
|
3448
|
+
/* Return the destination. */
|
|
3449
|
+
return dst;
|
|
3450
|
+
}
|
|
3451
|
+
|
|
3339
3452
|
|
|
3340
3453
|
/** Computes the C equal of two general values.
|
|
3341
3454
|
* @param src0 the first source value of the addition
|
|
@@ -3347,6 +3460,16 @@ Value equal_value_c(Value src0, Value src1, Value dst) {
|
|
|
3347
3460
|
return reduce_or_value(dst,dst);
|
|
3348
3461
|
}
|
|
3349
3462
|
|
|
3463
|
+
/** Computes the C equal of two general values treating Z as wildcards.
|
|
3464
|
+
* @param src0 the first source value of the addition
|
|
3465
|
+
* @param src1 the second source value of the addition
|
|
3466
|
+
* @param dst the destination value
|
|
3467
|
+
* @return the destination value */
|
|
3468
|
+
Value equal_value_z_c(Value src0, Value src1, Value dst) {
|
|
3469
|
+
dst = equal_value_z(src0,src1,dst);
|
|
3470
|
+
return reduce_or_value(dst,dst);
|
|
3471
|
+
}
|
|
3472
|
+
|
|
3350
3473
|
|
|
3351
3474
|
/** Computes the C not equal of two general values.
|
|
3352
3475
|
* @param src0 the first source value of the addition
|
|
@@ -471,6 +471,43 @@ void execute_statement(Statement stmnt, int mode, Behavior behavior) {
|
|
|
471
471
|
}
|
|
472
472
|
break;
|
|
473
473
|
}
|
|
474
|
+
case HCASEZ:
|
|
475
|
+
{
|
|
476
|
+
HCaseZ hcasez = (HCaseZ)stmnt;
|
|
477
|
+
/* Calculation the value to check. */
|
|
478
|
+
// Value value = calc_expression(hcasez->value);
|
|
479
|
+
Value value = get_value();
|
|
480
|
+
value = calc_expression(hcasez->value,value);
|
|
481
|
+
/* Tell if a casez if matched. */
|
|
482
|
+
int met = 0;
|
|
483
|
+
/* Check each case. */
|
|
484
|
+
Value cmp = get_value();
|
|
485
|
+
for(int i=0; i<hcasez->num_whens; ++i) {
|
|
486
|
+
// cmp = equal_value_z_c(value,calc_expression(hcasez->matches[i]),
|
|
487
|
+
// cmp);
|
|
488
|
+
Value match = get_value();
|
|
489
|
+
match = calc_expression(hcasez->matches[i],match);
|
|
490
|
+
cmp = equal_value_z_c(value,match,cmp);
|
|
491
|
+
if (is_defined_value(cmp) && value2integer(cmp)) {
|
|
492
|
+
/* Found the right case, execute the corresponding
|
|
493
|
+
* statement. */
|
|
494
|
+
execute_statement(hcasez->stmnts[i],mode,behavior);
|
|
495
|
+
/* And remeber it. */
|
|
496
|
+
met = 1;
|
|
497
|
+
free_value();
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
500
|
+
free_value();
|
|
501
|
+
}
|
|
502
|
+
free_value();
|
|
503
|
+
free_value();
|
|
504
|
+
/* Was no case found and is there a default statement? */
|
|
505
|
+
if (!met && hcasez->defolt) {
|
|
506
|
+
/* Yes, execute the default statement. */
|
|
507
|
+
execute_statement(hcasez->defolt,mode,behavior);
|
|
508
|
+
}
|
|
509
|
+
break;
|
|
510
|
+
}
|
|
474
511
|
case TIME_WAIT:
|
|
475
512
|
{
|
|
476
513
|
/* Get the value of the delay. */
|
|
@@ -2,25 +2,25 @@
|
|
|
2
2
|
# A benchmark for the logic operations.
|
|
3
3
|
system :logic_bench do
|
|
4
4
|
[3].inner :x,:y
|
|
5
|
-
[3].inner :s_not, :s_and, :s_or, :s_xor, :
|
|
5
|
+
[3].inner :s_not, :s_and, :s_or, :s_xor, :s_eq
|
|
6
6
|
|
|
7
7
|
signed[16].inner :a,:b,:shl,:shr
|
|
8
8
|
|
|
9
9
|
timed do
|
|
10
10
|
8.times do |i|
|
|
11
11
|
8.times do |j|
|
|
12
|
-
x
|
|
13
|
-
y
|
|
14
|
-
s_not
|
|
15
|
-
s_and
|
|
16
|
-
s_or
|
|
17
|
-
s_xor
|
|
18
|
-
|
|
12
|
+
x <= i
|
|
13
|
+
y <= j
|
|
14
|
+
s_not <= ~x
|
|
15
|
+
s_and <= x & y
|
|
16
|
+
s_or <= x | y
|
|
17
|
+
s_xor <= x ^ y
|
|
18
|
+
s_eq <= (x == y)
|
|
19
19
|
!10.ns
|
|
20
|
-
a
|
|
21
|
-
b
|
|
22
|
-
shl
|
|
23
|
-
shr
|
|
20
|
+
a <= i
|
|
21
|
+
b <= j
|
|
22
|
+
shl <= (a << b)
|
|
23
|
+
shr <= (a >> b)
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
system :assign_to_slice do
|
|
2
|
+
[8].inner :reg
|
|
3
|
+
|
|
4
|
+
timed do
|
|
5
|
+
!10.ns
|
|
6
|
+
reg[1..0] <= _b00
|
|
7
|
+
!10.ns
|
|
8
|
+
reg[3..2] <= _b01
|
|
9
|
+
!10.ns
|
|
10
|
+
reg[5..4] <= _b10
|
|
11
|
+
!10.ns
|
|
12
|
+
reg[7..6] <= _b11
|
|
13
|
+
!10.ns
|
|
14
|
+
reg[3..0] <= _ha
|
|
15
|
+
!10.ns
|
|
16
|
+
reg[7..4] <= _h5
|
|
17
|
+
!10.ns
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Test the casez statement.
|
|
2
|
+
|
|
3
|
+
# A benchmark for the case statement.
|
|
4
|
+
system :case_bench do
|
|
5
|
+
[8].inner :x, :z
|
|
6
|
+
|
|
7
|
+
par do
|
|
8
|
+
hcasez(x)
|
|
9
|
+
hwhen(_b0000_0000) { z <= 0 }
|
|
10
|
+
hwhen(_b000z_0001) { z <= 1 }
|
|
11
|
+
hwhen(_b00z0_0010) { z <= 4 }
|
|
12
|
+
hwhen(_b00zz_0011) { z <= 9 }
|
|
13
|
+
hwhen(_b0z00_0100) { z <= 16 }
|
|
14
|
+
hwhen(_b0z0z_0101) { z <= 25 }
|
|
15
|
+
hwhen(_b0zz0_0110) { z <= 36 }
|
|
16
|
+
hwhen(_b0zzz_0111) { z <= 49 }
|
|
17
|
+
hwhen(_bz000_1000) { z <= 64 }
|
|
18
|
+
hwhen(_bz00z_1001) { z <= 81 }
|
|
19
|
+
hwhen(_bz0z0_1010) { z <= 100 }
|
|
20
|
+
hwhen(_bz0zz_1011) { z <= 121 }
|
|
21
|
+
hwhen(_bzz00_1100) { z <= 144 }
|
|
22
|
+
hwhen(_bzz0z_1101) { z <= 169 }
|
|
23
|
+
hwhen(_bzzz0_1110) { z <= 196 }
|
|
24
|
+
hwhen(_bzzzz_1111) { z <= 225 }
|
|
25
|
+
helse { z <= _zzzzzzzz }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
timed do
|
|
29
|
+
!10.ns
|
|
30
|
+
20.times do |i|
|
|
31
|
+
x <= i
|
|
32
|
+
!10.ns
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -344,7 +344,7 @@ system :henmerable_checks do
|
|
|
344
344
|
|
|
345
345
|
par(clk.posedge) do
|
|
346
346
|
# hprint("}0\n")
|
|
347
|
-
vals.hzip([_h12]*8).
|
|
347
|
+
vals.hzip([_h12]*8).heach_with_index { |(a,b),i| res62[i] <= a+b }
|
|
348
348
|
end
|
|
349
349
|
|
|
350
350
|
# Test enumerators of values.
|
data/lib/HDLRuby/hruby_high.rb
CHANGED
|
@@ -777,7 +777,6 @@ module HDLRuby::High
|
|
|
777
777
|
# registered in the namespace stack, and one for creating an
|
|
778
778
|
# array of instances being registered in the Array class.
|
|
779
779
|
def make_instantiater(name,klass,&ruby_block)
|
|
780
|
-
# puts "make_instantiater with name=#{name}"
|
|
781
780
|
# Set the instanciater.
|
|
782
781
|
@instance_procs = [ ruby_block ]
|
|
783
782
|
# Set the target instantiation class.
|
|
@@ -794,7 +793,8 @@ module HDLRuby::High
|
|
|
794
793
|
# If no arguments, return the system as is
|
|
795
794
|
return obj if args.empty?
|
|
796
795
|
# Are there any generic arguments?
|
|
797
|
-
if ruby_block.arity > 0 then
|
|
796
|
+
if ruby_block.arity > 0 or args.size > 1 or args[0].is_a?(Hash) then
|
|
797
|
+
# if ruby_block.parameters.size > 0 then
|
|
798
798
|
# Yes, must specialize the system with the arguments.
|
|
799
799
|
# If arguments, create a new system specialized with them
|
|
800
800
|
return SystemT.new(:"") { include(obj,*args) }
|
|
@@ -1435,7 +1435,8 @@ module HDLRuby::High
|
|
|
1435
1435
|
return if self.metaif(condition,&ruby_block)
|
|
1436
1436
|
# Ensure there is a block.
|
|
1437
1437
|
ruby_block = proc {} unless block_given?
|
|
1438
|
-
self.par do
|
|
1438
|
+
# self.par do
|
|
1439
|
+
self.seq do # Seq for combinatorial is good practice
|
|
1439
1440
|
hif(condition,mode,&ruby_block)
|
|
1440
1441
|
end
|
|
1441
1442
|
end
|
|
@@ -1491,11 +1492,40 @@ module HDLRuby::High
|
|
|
1491
1492
|
# * a new behavior is created to enclose the hcase.
|
|
1492
1493
|
def hcase(value)
|
|
1493
1494
|
return if self.metacase(value)
|
|
1494
|
-
self.par do
|
|
1495
|
+
# self.par do
|
|
1496
|
+
self.seq do # Seq for combinatorial is good practice
|
|
1495
1497
|
hcase(value)
|
|
1496
1498
|
end
|
|
1497
1499
|
end
|
|
1498
1500
|
|
|
1501
|
+
# Creates a new case statement taking z was wildcard with a +value+ used for deciding which
|
|
1502
|
+
# block to execute.
|
|
1503
|
+
#
|
|
1504
|
+
# NOTE:
|
|
1505
|
+
# * the when part is defined through the hwhen method.
|
|
1506
|
+
# * a new behavior is created to enclose the hcase.
|
|
1507
|
+
def hcasez(value)
|
|
1508
|
+
return if self.metacase(value)
|
|
1509
|
+
# self.par do
|
|
1510
|
+
self.seq do # Seq for combinatorial is good practice
|
|
1511
|
+
hcasez(value)
|
|
1512
|
+
end
|
|
1513
|
+
end
|
|
1514
|
+
|
|
1515
|
+
# Creates a new case statement taking z as wildcards with a +value+ used for deciding which
|
|
1516
|
+
# block to execute.
|
|
1517
|
+
#
|
|
1518
|
+
# NOTE:
|
|
1519
|
+
# * the when part is defined through the hwhen method.
|
|
1520
|
+
# * a new behavior is created to enclose the hcase.
|
|
1521
|
+
def hcasez(value)
|
|
1522
|
+
return if self.metacase(value)
|
|
1523
|
+
# self.par do
|
|
1524
|
+
self.seq do # Seq for combinatorial is good practice
|
|
1525
|
+
hcasez(value)
|
|
1526
|
+
end
|
|
1527
|
+
end
|
|
1528
|
+
|
|
1499
1529
|
# Sets the block of a case structure executed when the +match+ is met
|
|
1500
1530
|
# to the block in +mode+ generated by the execution of +ruby_block+.
|
|
1501
1531
|
#
|
|
@@ -2337,6 +2367,7 @@ module HDLRuby::High
|
|
|
2337
2367
|
end
|
|
2338
2368
|
define_singleton_method(name.to_sym) do |*args|
|
|
2339
2369
|
if (args.size < ruby_block.arity) then
|
|
2370
|
+
# if (args.size < ruby_block.parameters.size) then
|
|
2340
2371
|
# Not enough arguments get generic type as is.
|
|
2341
2372
|
type
|
|
2342
2373
|
else
|
|
@@ -2350,6 +2381,7 @@ module HDLRuby::High
|
|
|
2350
2381
|
else
|
|
2351
2382
|
define_method(name.to_sym) do |*args|
|
|
2352
2383
|
if (args.size < ruby_block.arity) then
|
|
2384
|
+
# if (args.size < ruby_block.parameters.size) then
|
|
2353
2385
|
# Not enough arguments, get generic type as is.
|
|
2354
2386
|
type
|
|
2355
2387
|
else
|
|
@@ -2368,7 +2400,7 @@ module HDLRuby::High
|
|
|
2368
2400
|
def system(name = :"", *includes, &ruby_block)
|
|
2369
2401
|
# Ensure there is a block.
|
|
2370
2402
|
ruby_block = proc {} unless block_given?
|
|
2371
|
-
# print "system ruby_block=#{ruby_block}\n"
|
|
2403
|
+
# print "system name=#{name} ruby_block=#{ruby_block}\n"
|
|
2372
2404
|
# Creates the resulting system.
|
|
2373
2405
|
return SystemT.new(name,*includes,&ruby_block)
|
|
2374
2406
|
end
|
|
@@ -2523,6 +2555,9 @@ module HDLRuby::High
|
|
|
2523
2555
|
connects.each do |key,value|
|
|
2524
2556
|
# Gets the signal corresponding to connect.
|
|
2525
2557
|
signal = self.systemT.get_signal_with_included(key)
|
|
2558
|
+
unless signal then
|
|
2559
|
+
raise AnyError, "Invalid parameter: #{key}"
|
|
2560
|
+
end
|
|
2526
2561
|
# Check if it is an output.
|
|
2527
2562
|
isout = self.systemT.get_output_with_included(key)
|
|
2528
2563
|
# Convert it to a reference.
|
|
@@ -2826,7 +2861,7 @@ module HDLRuby::High
|
|
|
2826
2861
|
obj = self
|
|
2827
2862
|
::HDLRuby::High.cur_block.delete_statement!(obj)
|
|
2828
2863
|
# Handles the metaprogramming.
|
|
2829
|
-
return obj if self.metaif(condition
|
|
2864
|
+
return obj if self.metaif(condition) { add_statement(obj) }
|
|
2830
2865
|
# Creates the if statement.
|
|
2831
2866
|
stmnt = If.new(condition) { add_statement(obj) }
|
|
2832
2867
|
# Add it to the current block.
|
|
@@ -2935,9 +2970,11 @@ module HDLRuby::High
|
|
|
2935
2970
|
|
|
2936
2971
|
# Creates a new case statement with a +value+ that decides which
|
|
2937
2972
|
# block to execute.
|
|
2938
|
-
|
|
2973
|
+
# +mode+ is the mode the case should run in. For now there are
|
|
2974
|
+
# only two possiblities: normal case :"", and casez :casez
|
|
2975
|
+
def initialize(value, mode = :"")
|
|
2939
2976
|
# Create the yes block.
|
|
2940
|
-
super(value.to_expr)
|
|
2977
|
+
super(value.to_expr, mode)
|
|
2941
2978
|
end
|
|
2942
2979
|
|
|
2943
2980
|
# Sets the block executed in +mode+ when the value matches +match+.
|
|
@@ -2969,7 +3006,7 @@ module HDLRuby::High
|
|
|
2969
3006
|
# Converts the case to HDLRuby::Low.
|
|
2970
3007
|
def to_low
|
|
2971
3008
|
# Create the low level case.
|
|
2972
|
-
caseL = HDLRuby::Low::Case.new(@value.to_low)
|
|
3009
|
+
caseL = HDLRuby::Low::Case.new(@value.to_low,@mode)
|
|
2973
3010
|
# # For debugging: set the source high object
|
|
2974
3011
|
# caseL.properties[:low2high] = self.hdr_id
|
|
2975
3012
|
# self.properties[:high2low] = caseL
|
|
@@ -3185,12 +3222,12 @@ module HDLRuby::High
|
|
|
3185
3222
|
|
|
3186
3223
|
# Extends on the left to +n+ bits filling with +v+ bit values.
|
|
3187
3224
|
def ljust(n,v)
|
|
3188
|
-
|
|
3225
|
+
return [(v.to_s * (n-self.width)).to_value, self].to_expr
|
|
3189
3226
|
end
|
|
3190
3227
|
|
|
3191
3228
|
# Extends on the right to +n+ bits filling with +v+ bit values.
|
|
3192
3229
|
def rjust(n,v)
|
|
3193
|
-
|
|
3230
|
+
return [self, (v.to_s * (n-self.width)).to_value].to_expr
|
|
3194
3231
|
end
|
|
3195
3232
|
|
|
3196
3233
|
# Extends on the left to +n+ bits filling with 0.
|
|
@@ -3200,7 +3237,8 @@ module HDLRuby::High
|
|
|
3200
3237
|
|
|
3201
3238
|
# Extends on the left to +n+ bits preserving the signe.
|
|
3202
3239
|
def sext(n)
|
|
3203
|
-
return self.ljust(self[-1])
|
|
3240
|
+
# return self.ljust(n,self[-1])
|
|
3241
|
+
return self.as(HDLRuby::High.top_user.signed[self.type.width]).as(HDLRuby::High.top_user.signed[n])
|
|
3204
3242
|
end
|
|
3205
3243
|
|
|
3206
3244
|
# # Match the type with +typ+:
|
|
@@ -3741,6 +3779,9 @@ module HDLRuby::High
|
|
|
3741
3779
|
# Creates a new reference from a +base+ reference and named +object+.
|
|
3742
3780
|
def initialize(base,object)
|
|
3743
3781
|
# puts "New RefObjet with base=#{base}, object=#{object}"
|
|
3782
|
+
unless object
|
|
3783
|
+
raise AnyError, "Empty object for reference."
|
|
3784
|
+
end
|
|
3744
3785
|
if object.respond_to?(:type) then
|
|
3745
3786
|
# Typed object, so typed reference.
|
|
3746
3787
|
super(object.type)
|
|
@@ -4636,6 +4677,16 @@ module HDLRuby::High
|
|
|
4636
4677
|
self.add_statement(Case.new(value))
|
|
4637
4678
|
end
|
|
4638
4679
|
|
|
4680
|
+
# Creates a new case statement taking z as wildcard with a +value+ used for deciding which
|
|
4681
|
+
# block to execute.
|
|
4682
|
+
#
|
|
4683
|
+
# NOTE: the when part is defined through the hwhen method.
|
|
4684
|
+
def hcasez(value)
|
|
4685
|
+
return if self.metacase(value)
|
|
4686
|
+
# Creates the case statement.
|
|
4687
|
+
self.add_statement(Case.new(value, :casez))
|
|
4688
|
+
end
|
|
4689
|
+
|
|
4639
4690
|
# Sets the block of a case structure executed when the +match+ is met
|
|
4640
4691
|
# to the block in +mode+ generated by the execution of +ruby_block+.
|
|
4641
4692
|
#
|
|
@@ -5247,6 +5298,7 @@ module HDLRuby::High
|
|
|
5247
5298
|
class ::Float
|
|
5248
5299
|
# Converts to a new high-level expression.
|
|
5249
5300
|
def to_expr
|
|
5301
|
+
raise "Float not supported yet."
|
|
5250
5302
|
return Value.new(Real,self)
|
|
5251
5303
|
end
|
|
5252
5304
|
|
|
@@ -5399,6 +5451,38 @@ module HDLRuby::High
|
|
|
5399
5451
|
expr
|
|
5400
5452
|
end
|
|
5401
5453
|
|
|
5454
|
+
# Casts to +typ+.
|
|
5455
|
+
def as(typ)
|
|
5456
|
+
return self.to_expr.as(typ)
|
|
5457
|
+
end
|
|
5458
|
+
|
|
5459
|
+
# Converts to a bit vector.
|
|
5460
|
+
def to_bit
|
|
5461
|
+
return self.to_expr.to_bit
|
|
5462
|
+
end
|
|
5463
|
+
|
|
5464
|
+
# Casts to an unsigned bit vector type.
|
|
5465
|
+
def to_unsigned
|
|
5466
|
+
return self.to_bit.to_unsigned
|
|
5467
|
+
end
|
|
5468
|
+
|
|
5469
|
+
# Casts to a signed bit vector type.
|
|
5470
|
+
def to_signed
|
|
5471
|
+
return self.to_bit_to_signed
|
|
5472
|
+
end
|
|
5473
|
+
|
|
5474
|
+
# Extends on the left to +n+ bits filling with 0.
|
|
5475
|
+
def zext(n)
|
|
5476
|
+
return self.to_bit.zext(n)
|
|
5477
|
+
end
|
|
5478
|
+
|
|
5479
|
+
# Extends on the left to +n+ bits preserving the signe.
|
|
5480
|
+
def sext(n)
|
|
5481
|
+
return self.to_bit.sext(n)
|
|
5482
|
+
end
|
|
5483
|
+
|
|
5484
|
+
# Add the methods of HExpression
|
|
5485
|
+
|
|
5402
5486
|
# Converts to a new high-level reference.
|
|
5403
5487
|
def to_ref
|
|
5404
5488
|
expr = RefConcat.new(TypeTuple.new(:"",:little,*self.map do |elem|
|
|
@@ -5467,6 +5551,17 @@ module HDLRuby::High
|
|
|
5467
5551
|
end
|
|
5468
5552
|
end
|
|
5469
5553
|
|
|
5554
|
+
# Creates a hcase statement taking z as wildcard executing +ruby_block+ on the element of
|
|
5555
|
+
# the array selected by +value+
|
|
5556
|
+
def hcasez(value,&ruby_block)
|
|
5557
|
+
# Ensure there is a block.
|
|
5558
|
+
ruby_block = proc {} unless block_given?
|
|
5559
|
+
High.cur_block.hcasez(value)
|
|
5560
|
+
self.each.with_index do |elem,i|
|
|
5561
|
+
High.cur_block.hwhen(i) { ruby_block.call(elem) }
|
|
5562
|
+
end
|
|
5563
|
+
end
|
|
5564
|
+
|
|
5470
5565
|
# Moved to HArrow.
|
|
5471
5566
|
# # Add support of the left arrow operator.
|
|
5472
5567
|
# def <=(expr)
|
|
@@ -5792,6 +5887,20 @@ def self.configure_high
|
|
|
5792
5887
|
end
|
|
5793
5888
|
|
|
5794
5889
|
|
|
5890
|
+
|
|
5891
|
+
## Handling the properties that can be added to HDLRuby objects.
|
|
5892
|
+
|
|
5893
|
+
## Add to object +obj+, property +prop+.
|
|
5894
|
+
def self.add_property(obj,prop)
|
|
5895
|
+
HDLRuby::Low.add_property(obj,prop)
|
|
5896
|
+
end
|
|
5897
|
+
|
|
5898
|
+
## Iterate on the properties of object +obj+.
|
|
5899
|
+
def self.each_property(obj,&ruby_block)
|
|
5900
|
+
HDLRuby::Low.each_property(obj,&ruby_block)
|
|
5901
|
+
end
|
|
5902
|
+
|
|
5903
|
+
|
|
5795
5904
|
end
|
|
5796
5905
|
|
|
5797
5906
|
|
data/lib/HDLRuby/hruby_low.rb
CHANGED
|
@@ -36,8 +36,6 @@ module HDLRuby::Low
|
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
|
|
39
|
-
# Hdecorator = HDLRuby::Hdecorator
|
|
40
|
-
|
|
41
39
|
##
|
|
42
40
|
# Gives parent definition and access properties to an hardware object.
|
|
43
41
|
module Hparent
|
|
@@ -162,9 +160,6 @@ module HDLRuby::Low
|
|
|
162
160
|
end
|
|
163
161
|
end
|
|
164
162
|
|
|
165
|
-
# # Add decorator capability (modifies intialize to put after).
|
|
166
|
-
# include Hdecorator
|
|
167
|
-
|
|
168
163
|
# Comparison for hash: structural comparison.
|
|
169
164
|
def eql?(obj)
|
|
170
165
|
return false unless obj.is_a?(SystemT)
|
|
@@ -529,9 +524,6 @@ module HDLRuby::Low
|
|
|
529
524
|
@behaviors = []
|
|
530
525
|
end
|
|
531
526
|
|
|
532
|
-
# # Add decorator capability (modifies intialize to put after).
|
|
533
|
-
# include Hdecorator
|
|
534
|
-
|
|
535
527
|
# Comparison for hash: structural comparison.
|
|
536
528
|
def eql?(obj)
|
|
537
529
|
return false unless obj.is_a?(Scope)
|
|
@@ -1293,8 +1285,11 @@ module HDLRuby::Low
|
|
|
1293
1285
|
@name = name.to_sym
|
|
1294
1286
|
end
|
|
1295
1287
|
|
|
1296
|
-
#
|
|
1297
|
-
#
|
|
1288
|
+
# Converts the system to HDLRuby::Low.
|
|
1289
|
+
# Here already low.
|
|
1290
|
+
def to_low
|
|
1291
|
+
return self
|
|
1292
|
+
end
|
|
1298
1293
|
|
|
1299
1294
|
# Comparison for hash: structural comparison.
|
|
1300
1295
|
def eql?(obj)
|
|
@@ -1989,6 +1984,11 @@ module HDLRuby::Low
|
|
|
1989
1984
|
return true
|
|
1990
1985
|
end
|
|
1991
1986
|
|
|
1987
|
+
# Gets thebitwidth
|
|
1988
|
+
def width
|
|
1989
|
+
return self.reduce(0) {|sum,elem| sum + elem.width }
|
|
1990
|
+
end
|
|
1991
|
+
|
|
1992
1992
|
# Hash function.
|
|
1993
1993
|
def hash
|
|
1994
1994
|
return [super,@types].hash
|
|
@@ -2330,9 +2330,6 @@ module HDLRuby::Low
|
|
|
2330
2330
|
# @block = block
|
|
2331
2331
|
end
|
|
2332
2332
|
|
|
2333
|
-
# # Add decorator capability (modifies intialize to put after).
|
|
2334
|
-
# include Hdecorator
|
|
2335
|
-
|
|
2336
2333
|
# Sets the block if not already set.
|
|
2337
2334
|
def block=(block)
|
|
2338
2335
|
# Check the block.
|
|
@@ -2561,9 +2558,6 @@ module HDLRuby::Low
|
|
|
2561
2558
|
ref.parent = self
|
|
2562
2559
|
end
|
|
2563
2560
|
|
|
2564
|
-
# # Add decorator capability (modifies intialize to put after).
|
|
2565
|
-
# include Hdecorator
|
|
2566
|
-
|
|
2567
2561
|
# Comparison for hash: structural comparison.
|
|
2568
2562
|
def eql?(obj)
|
|
2569
2563
|
return false unless obj.is_a?(Event)
|
|
@@ -2698,9 +2692,6 @@ module HDLRuby::Low
|
|
|
2698
2692
|
@signals.each(&ruby_block) if @signals
|
|
2699
2693
|
end
|
|
2700
2694
|
|
|
2701
|
-
# # Add decorator capability (modifies intialize to put after).
|
|
2702
|
-
# include Hdecorator
|
|
2703
|
-
|
|
2704
2695
|
# Iterates over each object deeply.
|
|
2705
2696
|
#
|
|
2706
2697
|
# Returns an enumerator if no ruby block is given.
|
|
@@ -2783,9 +2774,6 @@ module HDLRuby::Low
|
|
|
2783
2774
|
@systemTs = [ @systemT ]
|
|
2784
2775
|
end
|
|
2785
2776
|
|
|
2786
|
-
# # Add decorator capability (modifies intialize to put after).
|
|
2787
|
-
# include Hdecorator
|
|
2788
|
-
|
|
2789
2777
|
# Iterates over each object deeply.
|
|
2790
2778
|
#
|
|
2791
2779
|
# Returns an enumerator if no ruby block is given.
|
|
@@ -2919,9 +2907,6 @@ module HDLRuby::Low
|
|
|
2919
2907
|
lumps.each { |lump| self.add_lump(lump) }
|
|
2920
2908
|
end
|
|
2921
2909
|
|
|
2922
|
-
# # Add decorator capability (modifies intialize to put after).
|
|
2923
|
-
# include Hdecorator
|
|
2924
|
-
|
|
2925
2910
|
# Adds a +lump+ of code, it is ment to become an expression or
|
|
2926
2911
|
# some text.
|
|
2927
2912
|
def add_lump(lump)
|
|
@@ -3101,9 +3086,6 @@ module HDLRuby::Low
|
|
|
3101
3086
|
@chunks = HashName.new
|
|
3102
3087
|
end
|
|
3103
3088
|
|
|
3104
|
-
# # Add decorator capability (modifies intialize to put after).
|
|
3105
|
-
# include Hdecorator
|
|
3106
|
-
|
|
3107
3089
|
# Adds a +chunk+ to the sensitivity list.
|
|
3108
3090
|
def add_chunk(chunk)
|
|
3109
3091
|
# Check and add the chunk.
|
|
@@ -3212,7 +3194,6 @@ module HDLRuby::Low
|
|
|
3212
3194
|
# NOTE: this is an abstract class which is not to be used directly.
|
|
3213
3195
|
class Statement
|
|
3214
3196
|
include Hparent
|
|
3215
|
-
# include Hdecorator
|
|
3216
3197
|
|
|
3217
3198
|
# Clones (deeply)
|
|
3218
3199
|
def clone
|
|
@@ -3700,9 +3681,6 @@ module HDLRuby::Low
|
|
|
3700
3681
|
match.parent = statement.parent = self
|
|
3701
3682
|
end
|
|
3702
3683
|
|
|
3703
|
-
# # Add decorator capability (modifies intialize to put after).
|
|
3704
|
-
# include Hdecorator
|
|
3705
|
-
|
|
3706
3684
|
# Iterates over each object deeply.
|
|
3707
3685
|
#
|
|
3708
3686
|
# Returns an enumerator if no ruby block is given.
|
|
@@ -3818,15 +3796,18 @@ module HDLRuby::Low
|
|
|
3818
3796
|
attr_reader :default
|
|
3819
3797
|
|
|
3820
3798
|
# Creates a new case statement whose excution flow is decided from
|
|
3821
|
-
# +value+ with a possible cases given in +whens+ and +default
|
|
3822
|
-
#
|
|
3823
|
-
|
|
3799
|
+
# +value+ with a possible cases given in +whens+ and +default+
|
|
3800
|
+
# (can be set later)
|
|
3801
|
+
# +mode+ is the mode the case should run in. For now there are two
|
|
3802
|
+
# possible modes: normal case :"", and in a mode where z are taken as wildcards :casez.
|
|
3803
|
+
def initialize(value, mode = :"", default = nil, whens = [])
|
|
3824
3804
|
# Check and set the value.
|
|
3825
3805
|
unless value.is_a?(Expression)
|
|
3826
3806
|
raise AnyError, "Invalid class for a value: #{value.class}"
|
|
3827
3807
|
end
|
|
3828
3808
|
super()
|
|
3829
3809
|
@value = value
|
|
3810
|
+
@mode = mode.to_sym
|
|
3830
3811
|
# And set its parent.
|
|
3831
3812
|
value.parent = self
|
|
3832
3813
|
# Checks and set the default case if any.
|
|
@@ -3994,7 +3975,7 @@ module HDLRuby::Low
|
|
|
3994
3975
|
# Clone the default if any.
|
|
3995
3976
|
default = @default ? @default.clone : nil
|
|
3996
3977
|
# Clone the case.
|
|
3997
|
-
return Case.new(@value.clone,default,(@whens.map do |w|
|
|
3978
|
+
return Case.new(@value.clone,@mode,default,(@whens.map do |w|
|
|
3998
3979
|
w.clone
|
|
3999
3980
|
end) )
|
|
4000
3981
|
end
|
|
@@ -4025,9 +4006,6 @@ module HDLRuby::Low
|
|
|
4025
4006
|
@unit = unit.to_sym
|
|
4026
4007
|
end
|
|
4027
4008
|
|
|
4028
|
-
# # Add decorator capability (modifies intialize to put after).
|
|
4029
|
-
# include Hdecorator
|
|
4030
|
-
|
|
4031
4009
|
# Iterates over each object deeply.
|
|
4032
4010
|
#
|
|
4033
4011
|
# Returns an enumerator if no ruby block is given.
|
|
@@ -4918,8 +4896,10 @@ module HDLRuby::Low
|
|
|
4918
4896
|
end
|
|
4919
4897
|
end
|
|
4920
4898
|
|
|
4921
|
-
#
|
|
4922
|
-
|
|
4899
|
+
# Gets the bit width of the expression.
|
|
4900
|
+
def width
|
|
4901
|
+
return @type.width
|
|
4902
|
+
end
|
|
4923
4903
|
|
|
4924
4904
|
# Comparison for hash: structural comparison.
|
|
4925
4905
|
def eql?(obj)
|
|
@@ -5023,6 +5003,7 @@ module HDLRuby::Low
|
|
|
5023
5003
|
|
|
5024
5004
|
# Creates a new value typed +type+ and containing +content+.
|
|
5025
5005
|
def initialize(type,content)
|
|
5006
|
+
# puts "New value with content=#{content} (content.class=#{content.class})"
|
|
5026
5007
|
super(type)
|
|
5027
5008
|
if content.nil? then
|
|
5028
5009
|
# Handle the nil content case.
|
|
@@ -5041,7 +5022,11 @@ module HDLRuby::Low
|
|
|
5041
5022
|
unless content.is_a?(Numeric) or
|
|
5042
5023
|
content.is_a?(HDLRuby::BitString)
|
|
5043
5024
|
# content = HDLRuby::BitString.new(content.to_s)
|
|
5044
|
-
|
|
5025
|
+
if content.is_a?(Array) then
|
|
5026
|
+
content = content.map(&:to_s).join
|
|
5027
|
+
else
|
|
5028
|
+
content = content.to_s
|
|
5029
|
+
end
|
|
5045
5030
|
if self.type.unsigned? && content[0] != "0" then
|
|
5046
5031
|
# content = "0" + content.rjust(self.type.width,content[0])
|
|
5047
5032
|
if content[0] == "1" then
|
|
@@ -5108,10 +5093,10 @@ module HDLRuby::Low
|
|
|
5108
5093
|
return self.content <=> value
|
|
5109
5094
|
end
|
|
5110
5095
|
|
|
5111
|
-
# Gets the bit width of the value.
|
|
5112
|
-
def width
|
|
5113
|
-
|
|
5114
|
-
end
|
|
5096
|
+
# # Gets the bit width of the value.
|
|
5097
|
+
# def width
|
|
5098
|
+
# return @type.width
|
|
5099
|
+
# end
|
|
5115
5100
|
|
|
5116
5101
|
# Tells if the value is even.
|
|
5117
5102
|
def even?
|
|
@@ -6449,4 +6434,23 @@ module HDLRuby::Low
|
|
|
6449
6434
|
end
|
|
6450
6435
|
|
|
6451
6436
|
end
|
|
6437
|
+
|
|
6438
|
+
|
|
6439
|
+
## Handling the properties that can be added to HDLRuby objects.
|
|
6440
|
+
|
|
6441
|
+
Properties = Hash.new
|
|
6442
|
+
|
|
6443
|
+
## Add to object +obj+, property +prop+.
|
|
6444
|
+
def self.add_property(obj,prop)
|
|
6445
|
+
Properties[obj] ||= Set.new
|
|
6446
|
+
Properties[obj] << prop
|
|
6447
|
+
obj
|
|
6448
|
+
end
|
|
6449
|
+
|
|
6450
|
+
## Iterate on the properties of object +obj+.
|
|
6451
|
+
def self.each_property(obj,&ruby_block)
|
|
6452
|
+
Properties[obj].each(&ruby_block)
|
|
6453
|
+
end
|
|
6454
|
+
|
|
6455
|
+
|
|
6452
6456
|
end
|
data/lib/HDLRuby/hruby_rcsim.rb
CHANGED
|
@@ -719,8 +719,13 @@ module HDLRuby::High
|
|
|
719
719
|
# Generate the C description of the hardware case.
|
|
720
720
|
def to_rcsim
|
|
721
721
|
# Create the hardware case C object.
|
|
722
|
-
@
|
|
723
|
-
|
|
722
|
+
if(@mode == :casez) then
|
|
723
|
+
@rcstatement = RCSim.rcsim_make_hcasez(self.value.to_rcsim,
|
|
724
|
+
self.default ? self.default.to_rcsim : nil)
|
|
725
|
+
else
|
|
726
|
+
@rcstatement = RCSim.rcsim_make_hcase(self.value.to_rcsim,
|
|
727
|
+
self.default ? self.default.to_rcsim : nil)
|
|
728
|
+
end
|
|
724
729
|
|
|
725
730
|
# Add the hardware whens.
|
|
726
731
|
rcsim_matches = self.each_when.map {|wh| wh.match.to_rcsim }
|
|
@@ -1562,10 +1562,14 @@ module HDLRuby::Low
|
|
|
1562
1562
|
# Converts the system to Verilog code.
|
|
1563
1563
|
def to_verilog
|
|
1564
1564
|
# if self.base.name.to_s != "bit"
|
|
1565
|
+
first = self.range.first
|
|
1566
|
+
first = first.to_verilog if first.is_a?(Expression)
|
|
1567
|
+
last = self.range.last
|
|
1568
|
+
last = last.to_verilog if last.is_a?(Expression)
|
|
1565
1569
|
if VERILOG_BASE_TYPES.include?(self.base.name.to_s)
|
|
1566
|
-
|
|
1570
|
+
return " #{self.base.name.to_s}[#{first}:#{last}]"
|
|
1567
1571
|
end
|
|
1568
|
-
return " [#{
|
|
1572
|
+
return " [#{first}:#{last}]"
|
|
1569
1573
|
end
|
|
1570
1574
|
end
|
|
1571
1575
|
|
|
@@ -1630,9 +1634,9 @@ module HDLRuby::Low
|
|
|
1630
1634
|
res = ""
|
|
1631
1635
|
sels = self.select.to_verilog
|
|
1632
1636
|
@choices[0..-2].each_with_index do |choice,i|
|
|
1633
|
-
res << "#{sels} == #{i} ? #{choice.to_verilog} : "
|
|
1637
|
+
res << "(#{sels} == #{i} ? #{choice.to_verilog} : "
|
|
1634
1638
|
end
|
|
1635
|
-
res << @choices[-1].to_verilog
|
|
1639
|
+
res << @choices[-1].to_verilog + (")" * @choices[0..-2].size)
|
|
1636
1640
|
return res
|
|
1637
1641
|
end
|
|
1638
1642
|
end
|
|
@@ -1676,6 +1680,9 @@ module HDLRuby::Low
|
|
|
1676
1680
|
# return "#{self.type.width}'b#{str}"
|
|
1677
1681
|
else
|
|
1678
1682
|
str = self.content.to_verilog
|
|
1683
|
+
if str.length > self.type.width then
|
|
1684
|
+
str = str[str.length-self.type.width..-1]
|
|
1685
|
+
end
|
|
1679
1686
|
if self.content.negative? then
|
|
1680
1687
|
return "#{str.length}'sb#{str}"
|
|
1681
1688
|
else
|
|
@@ -1738,7 +1745,11 @@ module HDLRuby::Low
|
|
|
1738
1745
|
|
|
1739
1746
|
result = " " * spc # Indented based on space_count.
|
|
1740
1747
|
|
|
1741
|
-
|
|
1748
|
+
if @mode == :casez then
|
|
1749
|
+
result << "casez(#{self.value.to_verilog})\n"
|
|
1750
|
+
else
|
|
1751
|
+
result << "case(#{self.value.to_verilog})\n"
|
|
1752
|
+
end
|
|
1742
1753
|
|
|
1743
1754
|
# n the case statement, each branch is partitioned by when. Process each time when.
|
|
1744
1755
|
self.each_when do |whens|
|
|
@@ -2150,7 +2161,7 @@ module HDLRuby::Low
|
|
|
2150
2161
|
inout = self.each_inout.to_a
|
|
2151
2162
|
|
|
2152
2163
|
# Spelling necessary for simulation.
|
|
2153
|
-
code = "`timescale
|
|
2164
|
+
code = "`timescale 10ps/1ps\n\n"
|
|
2154
2165
|
|
|
2155
2166
|
# self.properties[:verilog_name] = vname
|
|
2156
2167
|
# Output the module name.
|
data/lib/HDLRuby/std/decoder.rb
CHANGED
|
@@ -131,10 +131,10 @@ module HDLRuby::High::Std
|
|
|
131
131
|
format = format.to_s
|
|
132
132
|
width = format.size
|
|
133
133
|
# For that purpose create the regular expression used to process it.
|
|
134
|
-
prs = "([0-1]+)|(a+)|(b+)|(c+)|(d+)|(e+)|(g+)|(h+)|(i+)|(j+)|(k+)|(l+)|(m+)|(n+)|(o+)|(p+)|(q+)|(r+)|(s+)|(t+)|(u+)|(v+)|(w+)|(x+)|(y+)|(z+)"
|
|
134
|
+
prs = "([0-1]+)|(a+)|(b+)|(c+)|(d+)|(e+)|(f+)|(g+)|(h+)|(i+)|(j+)|(k+)|(l+)|(m+)|(n+)|(o+)|(p+)|(q+)|(r+)|(s+)|(t+)|(u+)|(v+)|(w+)|(x+)|(y+)|(z+)"
|
|
135
135
|
# Check if the format is compatible with it.
|
|
136
136
|
unless format =~ Regexp.new("^(#{prs})+$") then
|
|
137
|
-
raise AnyError
|
|
137
|
+
raise AnyError, "Invalid format for a field: #{format}"
|
|
138
138
|
end
|
|
139
139
|
# Split the format in fields.
|
|
140
140
|
format = format.split(Regexp.new(prs)).select {|str| !str.empty?}
|
|
@@ -889,6 +889,34 @@ module VerilogTools
|
|
|
889
889
|
state.indent = indent
|
|
890
890
|
state.level = level
|
|
891
891
|
return case_txt
|
|
892
|
+
when :casez
|
|
893
|
+
# Saves the state.
|
|
894
|
+
indent = state.indent
|
|
895
|
+
level = state.level
|
|
896
|
+
# Generate the hcase.
|
|
897
|
+
state.indent += " "
|
|
898
|
+
case_txt = indent + "hcasez(" + ast[1].to_HDLRuby(state) + ")\n"
|
|
899
|
+
# Generate the case items.
|
|
900
|
+
case_txt += ast[2].map do |item|
|
|
901
|
+
res_txt = ""
|
|
902
|
+
if item[0] != "default" then
|
|
903
|
+
# hwhen case.
|
|
904
|
+
res_txt += indent + "hwhen("
|
|
905
|
+
res_txt += item[0].map {|e| e.to_HDLRuby(state) }.join(",")
|
|
906
|
+
res_txt += ") do\n"
|
|
907
|
+
res_txt += item[1].to_HDLRuby(state)
|
|
908
|
+
res_txt += indent + "end\n"
|
|
909
|
+
else
|
|
910
|
+
# helse case.
|
|
911
|
+
res_txt += indent + "helse do\n"
|
|
912
|
+
res_txt += item[1].to_HDLRuby(state) + indent + "end\n"
|
|
913
|
+
end
|
|
914
|
+
res_txt
|
|
915
|
+
end.join
|
|
916
|
+
# Restore the state and return the result.
|
|
917
|
+
state.indent = indent
|
|
918
|
+
state.level = level
|
|
919
|
+
return case_txt
|
|
892
920
|
when :blocking_assignment, :non_blocking_assignment
|
|
893
921
|
return ast[0].to_HDLRuby(state)
|
|
894
922
|
when :statement
|
|
@@ -1094,6 +1122,8 @@ module VerilogTools
|
|
|
1094
1122
|
base = ast[1] ? ast[1].to_HDLRuby(state) : ""
|
|
1095
1123
|
# Get the second number if any.
|
|
1096
1124
|
number1 = ast[2] ? ast[2].to_HDLRuby(state) : ""
|
|
1125
|
+
# In HDLRuby, for now, wildcards work like z.
|
|
1126
|
+
number1 = number1.gsub("?","z")
|
|
1097
1127
|
# Depending on the base.
|
|
1098
1128
|
case base
|
|
1099
1129
|
when "'b"
|
|
@@ -1220,7 +1220,7 @@ module VerilogTools
|
|
|
1220
1220
|
CLOSE_BRA_COLON_TOKS = [ "\\" + CLOSE_BRA_TOK, COLON_TOK ]
|
|
1221
1221
|
CLOSE_BRA_COLON_REX = /\G#{S}(#{CLOSE_BRA_COLON_TOKS.join("|")})/
|
|
1222
1222
|
|
|
1223
|
-
STATEMENT_TOKS = [ IF_TOK,
|
|
1223
|
+
STATEMENT_TOKS = [ IF_TOK, CASEZ_TOK, CASEX_TOK, CASE_TOK,
|
|
1224
1224
|
FOREVER_TOK, REPEAT_TOK, WHILE_TOK, FOR_TOK,
|
|
1225
1225
|
WAIT_TOK, RIGHT_ARROW_TOK, DISABLE_TOK,
|
|
1226
1226
|
ASSIGN_TOK, FORCE_TOK, DEASSIGN_TOK, RELEASE_TOK ]
|
data/lib/HDLRuby/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: HDLRuby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.9.
|
|
4
|
+
version: 3.9.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lovic Gauthier
|
|
@@ -193,11 +193,13 @@ files:
|
|
|
193
193
|
- lib/HDLRuby/hdr_samples/tuple.rb
|
|
194
194
|
- lib/HDLRuby/hdr_samples/type_minmax_bench.rb
|
|
195
195
|
- lib/HDLRuby/hdr_samples/verilog_parser_bench.rb
|
|
196
|
+
- lib/HDLRuby/hdr_samples/with_assign_to_slice.rb
|
|
196
197
|
- lib/HDLRuby/hdr_samples/with_board.rb
|
|
197
198
|
- lib/HDLRuby/hdr_samples/with_board_sequencer.rb
|
|
198
199
|
- lib/HDLRuby/hdr_samples/with_bram.rb
|
|
199
200
|
- lib/HDLRuby/hdr_samples/with_bram_frame_stack.rb
|
|
200
201
|
- lib/HDLRuby/hdr_samples/with_bram_stack.rb
|
|
202
|
+
- lib/HDLRuby/hdr_samples/with_casez.rb
|
|
201
203
|
- lib/HDLRuby/hdr_samples/with_casts.rb
|
|
202
204
|
- lib/HDLRuby/hdr_samples/with_channel.rb
|
|
203
205
|
- lib/HDLRuby/hdr_samples/with_channel_other.rb
|
|
@@ -502,7 +504,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
502
504
|
- !ruby/object:Gem::Version
|
|
503
505
|
version: '0'
|
|
504
506
|
requirements: []
|
|
505
|
-
rubygems_version: 4.0.
|
|
507
|
+
rubygems_version: 4.0.18
|
|
506
508
|
specification_version: 4
|
|
507
509
|
summary: HDLRuby is a library for describing and simulating digital electronic systems.
|
|
508
510
|
test_files: []
|