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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2158fa1453147b4f00983a8e182f592a7878a3314fdabb351e79da00c99eb875
4
- data.tar.gz: db538f8d85886189c4d309acf9ed6e5e9239e0bbe7a7b380c22a768d20eca52f
3
+ metadata.gz: 00a784914e79391b0aa065086641989892907de384b64b3b43b221587076fcf4
4
+ data.tar.gz: b53f9aa4f668cd8a736f476b4c8b86572ec8572f00f09ba85bfd484e67ff3fc6
5
5
  SHA512:
6
- metadata.gz: 210bf9b4b29db252d1c7364d70aea07473381e8eb5500cf936edae1f01cd67d37cff69e5cff9391b65b6265b3e8261f87ec8335b75cae577379fe70304f0ef78
7
- data.tar.gz: 7c4e9e1ff74dcba76224505182b506363f772795a45e1608918d4b60648faed104b3776fdb459964e9900633448bbdb59af6c8259e309d9da329f6834c250f8b
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 (`hcase`).
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);
@@ -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
- /** Computes the equal (!XOR) of two bitstring values.
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
- /* Compute the width of sources in bits. */
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
- /* Update the destination capacity if required. */
1747
+ /* update the destination capacity if required. */
1748
1748
  resize_value(dst,width0);
1749
- /* Set the type and size of the destination from the type of the source.*/
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
- /* Get access to the data of the sources. */
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
- /* Get access to the data of the destination. */
1756
+ /* get access to the data of the destination. */
1757
1757
  char *dst_data = dst->data_str;
1758
1758
 
1759
- /* Get the sign extension character of source 1 and convert it to a bit.*/
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
- /* Perform the !xor. */
1762
+ /* perform the !xor. */
1763
1763
  unsigned long long count;
1764
- /* Check if values are the same. */
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'; /* Get and convert to bit. */
1767
+ char d0 = src0_data[count] - '0'; /* get and convert to bit. */
1768
1768
  char d1;
1769
1769
  if (count < width1) {
1770
- /* Still within source 1. */
1771
- d1 = src1_data[count] - '0';/* Get and convert to bit. */
1770
+ /* still within source 1. */
1771
+ d1 = src1_data[count] - '0';/* get and convert to bit. */
1772
1772
  } else {
1773
- /* Outside source 1, use the sign extension. */
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
- /* Undefined. */
1785
+ /* undefined. */
1786
1786
  same = 'x';
1787
1787
  break;
1788
1788
  }
1789
1789
  } else {
1790
- /* Undefined. */
1790
+ /* undefined. */
1791
1791
  same = 'x';
1792
1792
  break;
1793
1793
  }
1794
1794
  }
1795
- /* Set the destination to 0 or 1 depending of different. */
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
- /* Return the destination. */
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 (!XOR) of two general values.
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. */
@@ -1,4 +1,4 @@
1
- # Test the comparison operators.
1
+ # Test the case.
2
2
 
3
3
  # A benchmark for the case statement.
4
4
  system :case_bench do
@@ -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, :s_nxor
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 <= 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_nxor <= (x == y)
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 <= i
21
- b <= j
22
- shl <= (a << b)
23
- shr <= (a >> b)
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).each_with_index { |(a,b),i| res62[i] <= a+b }
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.
@@ -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,proc { add_statement(obj) })
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
- def initialize(value)
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
- return [(v.to_s * (n-self.width)).to_expr, self]
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
- return [self, (v.to_s * (n-self.width)).to_expr]
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
 
@@ -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
- # # Add decorator capability (modifies intialize to put after).
1297
- # include Hdecorator
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
- # + (can be set later)
3823
- def initialize(value, default = nil, whens = [])
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
- # # Add decorator capability (modifies intialize to put after).
4922
- # include Hdecorator
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
- content = content.to_s
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
- return @type.width
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
@@ -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
- @rcstatement = RCSim.rcsim_make_hcase(self.value.to_rcsim,
723
- self.default ? self.default.to_rcsim : nil)
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
- return " #{self.base.name.to_s}[#{self.range.first}:#{self.range.last}]"
1570
+ return " #{self.base.name.to_s}[#{first}:#{last}]"
1567
1571
  end
1568
- return " [#{self.range.first}:#{self.range.last}]"
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
- result << "case(#{self.value.to_verilog})\n"
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 1ps/1ps\n\n"
2164
+ code = "`timescale 10ps/1ps\n\n"
2154
2165
 
2155
2166
  # self.properties[:verilog_name] = vname
2156
2167
  # Output the module name.
@@ -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("Invalid format for a field: #{format}")
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, CASE_TOK, CASEZ_TOK, CASEX_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 ]
@@ -1,3 +1,3 @@
1
1
  module HDLRuby
2
- VERSION = "3.9.5"
2
+ VERSION = "3.9.6"
3
3
  end
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.5
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.14
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: []