HDLRuby 2.11.11 → 2.11.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +55 -18
- data/ext/hruby_sim/hruby_rcsim_build.c +27 -0
- data/ext/hruby_sim/hruby_sim.h +3 -0
- data/ext/hruby_sim/hruby_sim_core.c +17 -5
- data/ext/hruby_sim/hruby_sim_stack_calc.c +1 -1
- data/ext/hruby_sim/hruby_sim_tree_calc.c +8 -1
- data/ext/hruby_sim/hruby_sim_vcd.c +24 -7
- data/ext/hruby_sim/hruby_sim_vizualize.c +9 -1
- data/lib/HDLRuby/hdr_samples/constant_in_function.rb +3 -1
- data/lib/HDLRuby/hdr_samples/counter_dff_bench.rb +3 -1
- data/lib/HDLRuby/hdr_samples/huge_rom.rb +1 -1
- data/lib/HDLRuby/hdr_samples/mei8.rb +11 -11
- data/lib/HDLRuby/hdr_samples/mei8_bench.rb +11 -11
- data/lib/HDLRuby/hdr_samples/neg_arith_bench.rb +4 -4
- data/lib/HDLRuby/hdr_samples/rom_nest.rb +1 -1
- data/lib/HDLRuby/hdr_samples/ruby_fir_hw.rb +4 -4
- data/lib/HDLRuby/hdr_samples/struct.rb +44 -10
- data/lib/HDLRuby/hdr_samples/with_bram.rb +45 -0
- data/lib/HDLRuby/hdr_samples/with_casts.rb +3 -3
- data/lib/HDLRuby/hdr_samples/with_concat.rb +6 -6
- data/lib/HDLRuby/hdr_samples/with_connector_memory.rb +2 -2
- data/lib/HDLRuby/hdr_samples/with_def.rb +10 -3
- data/lib/HDLRuby/hdr_samples/with_define_operator.rb +44 -0
- data/lib/HDLRuby/hdr_samples/with_fixpoint.rb +12 -12
- data/lib/HDLRuby/hdr_samples/with_init.rb +3 -3
- data/lib/HDLRuby/hdr_samples/with_leftright.rb +21 -0
- data/lib/HDLRuby/hdr_samples/with_reduce.rb +13 -13
- data/lib/HDLRuby/hdr_samples/with_ref_array.rb +6 -6
- data/lib/HDLRuby/hdr_samples/with_subsums.rb +3 -3
- data/lib/HDLRuby/hdr_samples/with_terminate.rb +3 -3
- data/lib/HDLRuby/hdr_samples/with_to_a.rb +10 -10
- data/lib/HDLRuby/hdr_samples/with_values.rb +3 -3
- data/lib/HDLRuby/hdrcc.rb +14 -1
- data/lib/HDLRuby/hruby_bstr.rb +10 -5
- data/lib/HDLRuby/hruby_high.rb +114 -27
- data/lib/HDLRuby/hruby_low.rb +187 -16
- data/lib/HDLRuby/hruby_low2c.rb +71 -11
- data/lib/HDLRuby/hruby_low2vhd.rb +2 -1
- data/lib/HDLRuby/hruby_low_fix_types.rb +1 -0
- data/lib/HDLRuby/hruby_low_mutable.rb +30 -1
- data/lib/HDLRuby/hruby_low_resolve.rb +15 -2
- data/lib/HDLRuby/hruby_low_without_concat.rb +28 -8
- data/lib/HDLRuby/hruby_low_without_parinseq.rb +14 -4
- data/lib/HDLRuby/hruby_low_without_select.rb +2 -2
- data/lib/HDLRuby/hruby_low_without_subsignals.rb +279 -0
- data/lib/HDLRuby/hruby_rcsim.rb +80 -71
- data/lib/HDLRuby/hruby_rsim.rb +132 -7
- data/lib/HDLRuby/hruby_rsim_vcd.rb +99 -27
- data/lib/HDLRuby/hruby_values.rb +35 -31
- data/lib/HDLRuby/std/bram.rb +22 -0
- data/lib/HDLRuby/std/fixpoint.rb +2 -2
- data/lib/HDLRuby/std/fsm.rb +20 -3
- data/lib/HDLRuby/std/function_generator.rb +2 -2
- data/lib/HDLRuby/version.rb +1 -1
- metadata +7 -3
- data/lib/HDLRuby/hdr_samples/sumprod.rb +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 41a83b15623015119b3b9413b535614c9e99b92500e49d52ad6b14cd44fcc158
|
4
|
+
data.tar.gz: 38b0fea433d9d418998d72b03639fb02cc84c7345dd7f3a7c40c802166af0a41
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ac1c2e087bc1f3c55c7520d9f88230279a12e6500c7321683cd440d122436126e3335199bd1824d3f3018b2af82683a49c4c6982a41dfe5227a64e51519ff29c
|
7
|
+
data.tar.gz: 51de0a48243b54f5c5ffc9716609b2aba2604a7604c15938888c50139846f97e69267ace1044e2c3e111cc00bd70e77d4af378980214a6ee3ff1062c8181faba
|
data/README.md
CHANGED
@@ -437,7 +437,7 @@ system :sumprod do |typ,coefs|
|
|
437
437
|
typ[coefs.size].input :ins
|
438
438
|
typ.output :o
|
439
439
|
|
440
|
-
o <= coefs.each_with_index.reduce(
|
440
|
+
o <= coefs.each_with_index.reduce(_b0) do |sum,(coef,i)|
|
441
441
|
sum + ins[i]*coef
|
442
442
|
end
|
443
443
|
end
|
@@ -446,7 +446,7 @@ end
|
|
446
446
|
In the code above, there are two generic parameters,
|
447
447
|
`typ`, which indicates the data type of the circuit, and `coefs`, which is assumed to be an array of coefficients. Since the number of inputs depends on the number of provided coefficients, it is declared as an array of `width` bit signed whose size is equal to the number of coefficients.
|
448
448
|
|
449
|
-
The description of the sum of products may be more difficult to understand for people not familiar with the Ruby language. The `each_with_index` method iterates over the coefficients adding their index as iteration variable, the resulting operation (i.e., the iteration loop) is then modified by the `reduce` method that accumulates the code passed as arguments. This code, starting by `|sum,coef,i|` simply performs the addition of the current accumulation result (`sum`) with the product of the current coefficient (`coef`) and input (`ins[i]`, where `i` is the index) in the iteration. The argument `
|
449
|
+
The description of the sum of products may be more difficult to understand for people not familiar with the Ruby language. The `each_with_index` method iterates over the coefficients adding their index as iteration variable, the resulting operation (i.e., the iteration loop) is then modified by the `reduce` method that accumulates the code passed as arguments. This code, starting by `|sum,coef,i|` simply performs the addition of the current accumulation result (`sum`) with the product of the current coefficient (`coef`) and input (`ins[i]`, where `i` is the index) in the iteration. The argument `_b0` initializes the sum to `0`.
|
450
450
|
|
451
451
|
While slightly longer than the previous description, this description allows declaring a circuit implementing a sum of products with any bit width and any number of coefficients. For instance, the following code describes a signed 32-bit sum of products with 16 coefficients (just random numbers here).
|
452
452
|
|
@@ -463,7 +463,7 @@ system :sumprod_func do |typ,coefs|
|
|
463
463
|
typ[coefs.size].input ins
|
464
464
|
typ.output :o
|
465
465
|
|
466
|
-
o <= coefs.each_with_index.reduce(
|
466
|
+
o <= coefs.each_with_index.reduce(_b0) do
|
467
467
|
|sum,(coef,i)|
|
468
468
|
add(sum, mult(ins[i]*coef))
|
469
469
|
end
|
@@ -509,7 +509,7 @@ system :sumprod_proc do |add,mult,typ,coefs|
|
|
509
509
|
typ[coefs.size].input ins
|
510
510
|
typ.output :o
|
511
511
|
|
512
|
-
o <= coefs.each_with_index.reduce(
|
512
|
+
o <= coefs.each_with_index.reduce(_b0) do
|
513
513
|
|sum,(coef,i)|
|
514
514
|
add.(sum, mult.(ins[i]*coef))
|
515
515
|
end
|
@@ -539,10 +539,8 @@ A second possible approach provided by HDLRuby is to declare a new data type wit
|
|
539
539
|
signed[16].typedef(:sat16_1000)
|
540
540
|
|
541
541
|
sat16_1000.define_operator(:+) do |x,y|
|
542
|
-
|
543
|
-
|
544
|
-
res <= x + y
|
545
|
-
( res <= 1000 ).hif(res > 1000)
|
542
|
+
tmp = x + y
|
543
|
+
mux(tmp > 1000,tmp,1000)
|
546
544
|
end
|
547
545
|
end
|
548
546
|
```
|
@@ -565,10 +563,8 @@ end
|
|
565
563
|
|
566
564
|
|
567
565
|
sat.define_operator(:+) do |width,max, x,y|
|
568
|
-
|
569
|
-
|
570
|
-
res <= x + y
|
571
|
-
( res <= max ).hif(res > max)
|
566
|
+
tmp = x + y
|
567
|
+
mux(tmp > max, tmp, max)
|
572
568
|
end
|
573
569
|
end
|
574
570
|
```
|
@@ -1426,7 +1422,7 @@ They include [immediate values](#values), [reference to signals](#references) an
|
|
1426
1422
|
### Immediate values
|
1427
1423
|
<a name="values"></a>
|
1428
1424
|
|
1429
|
-
The immediate values of HDLRuby can represent vectors of `bit`, `unsigned`, and `signed`, and integer or floating-point numbers. They are prefixed by a `_` character and include a header that indicates the vector type and the base used for representing the value, followed by a numeral representing the value.
|
1425
|
+
The immediate values of HDLRuby can represent vectors of `bit`, `unsigned`, and `signed`, and integer or floating-point numbers. They are prefixed by a `_` character and include a header that indicates the vector type and the base used for representing the value, followed by a numeral representing the value. The bit width of a value is obtained by default from the width of the numeral, but it is also possible to specify it in the header. In addition, the character `_` can be put anywhere in the number for increasing the readability, it will be ignored.
|
1430
1426
|
|
1431
1427
|
The vector type specifiers are the followings:
|
1432
1428
|
|
@@ -1438,7 +1434,7 @@ The vector type specifiers are the followings:
|
|
1438
1434
|
|
1439
1435
|
The base specifiers are the followings:
|
1440
1436
|
|
1441
|
-
- `b`: binary,
|
1437
|
+
- `b`: binary,
|
1442
1438
|
|
1443
1439
|
- `o`: octal,
|
1444
1440
|
|
@@ -1446,21 +1442,30 @@ The base specifiers are the followings:
|
|
1446
1442
|
|
1447
1443
|
- `h`: hexadecimal.
|
1448
1444
|
|
1449
|
-
For example, all the following immediate values represent an 8-bit `
|
1445
|
+
For example, all the following immediate values represent an 8-bit `hundred` (either in unsigned or signed representation):
|
1450
1446
|
|
1451
1447
|
```ruby
|
1452
1448
|
_bb01100100
|
1453
|
-
|
1449
|
+
_b8b110_0100
|
1454
1450
|
_b01100100
|
1455
|
-
_01100100
|
1456
1451
|
_u8d100
|
1457
1452
|
_s8d100
|
1458
1453
|
_uh64
|
1459
1454
|
_s8o144
|
1460
1455
|
```
|
1461
1456
|
|
1457
|
+
Finally, it is possible to omit either the type specifier, the default being unsigned bit, or the base specifier, the default being binary. For example, all the following immediate values represent an 8-bit unsigned `hundred`:
|
1458
|
+
|
1459
|
+
```ruby
|
1460
|
+
_b01100100
|
1461
|
+
_h64
|
1462
|
+
_o144
|
1463
|
+
```
|
1464
|
+
|
1462
1465
|
__Notes__:
|
1463
1466
|
|
1467
|
+
- `_01100100` used to be considered as equivalent to `_b01100100`, however due to compatibility troubles with recent version of Ruby it is considered deprecated.
|
1468
|
+
|
1464
1469
|
- Ruby immediate values can also be used, their bit width is automatically adjusted to match the data type of the expression they are used in. Please notice this adjusting may change the value of the immediate, for example, the following code will set `sig` to 4 instead of 100:
|
1465
1470
|
|
1466
1471
|
```ruby
|
@@ -2309,7 +2314,7 @@ Where:
|
|
2309
2314
|
* `type` is the type from which the operation is overloaded.
|
2310
2315
|
* `op` is the operator that is overloaded (e.g., `+`)
|
2311
2316
|
* `args` are the arguments of the operation.
|
2312
|
-
* `operation description` is an HDLRuby
|
2317
|
+
* `operation description` is an HDLRuby expression of the new operation.
|
2313
2318
|
|
2314
2319
|
For example, for `fix32` a 32-bit (decimal point at 16-bit) fixed-point type defined as follows:
|
2315
2320
|
|
@@ -2813,6 +2818,38 @@ fsm(clk.posedge,rst,:sync) do
|
|
2813
2818
|
end
|
2814
2819
|
```
|
2815
2820
|
|
2821
|
+
__Note__: the goto statements acts globally, i.e., they are independant of the place where they are declared within the state. For example for both following statements, the next state will always be `st_a` whatever `cond` maybe:
|
2822
|
+
|
2823
|
+
```ruby
|
2824
|
+
state(:st_0) do
|
2825
|
+
goto(:st_a)
|
2826
|
+
end
|
2827
|
+
state(:st_1) do
|
2828
|
+
hif(cond) { goto(:st_a) }
|
2829
|
+
end
|
2830
|
+
```
|
2831
|
+
|
2832
|
+
That is to say, for a conditional `goto` for `st_1` the code should have been written as follows:
|
2833
|
+
|
2834
|
+
```ruby
|
2835
|
+
state(:st_1) do
|
2836
|
+
goto(cond,:st_a)
|
2837
|
+
end
|
2838
|
+
```
|
2839
|
+
|
2840
|
+
The use of `goto` makes the design of FSM shorter for a majority of the cases, be sometimes, a finer control is required. For that purpose it is also possible to configure the FSM is `static` mode where the `next_state` statement that indicates implicitly the next state. Putting is static mode is done by passing `:static` as argument when declaring the FSM. For example the following FSM uses `next_state` to specify explicitly the next states depending on some condition signals `cond0` and `cond1`:
|
2841
|
+
|
2842
|
+
```ruby
|
2843
|
+
fsm(clk.posedge,rst,:static)
|
2844
|
+
state(:st_0) do
|
2845
|
+
next_state(:st_1)
|
2846
|
+
state(:st_1) do
|
2847
|
+
hif(cond) { next_state(:st_1) }
|
2848
|
+
helse { next_state(:st_0) }
|
2849
|
+
end
|
2850
|
+
end
|
2851
|
+
```
|
2852
|
+
|
2816
2853
|
|
2817
2854
|
## Fixed-point (fixpoint)
|
2818
2855
|
<a name="fixpoint"></a>
|
@@ -319,6 +319,9 @@ VALUE rcsim_make_signal(VALUE mod, VALUE name, VALUE type) {
|
|
319
319
|
// printf("Creating signal named=%s\n",signal->name);
|
320
320
|
value_to_rcsim(TypeS,type,signal->type);
|
321
321
|
// printf("&type=%p type=%p width=%llu\n",&(signal->type),signal->type,type_width(signal->type));
|
322
|
+
signal->num_signals= 0;
|
323
|
+
signal->signals = NULL;
|
324
|
+
|
322
325
|
signal->c_value = make_value(signal->type,0);
|
323
326
|
// printf("signal->c_value=%p\n",signal->c_value);
|
324
327
|
signal->c_value->signal = signal;
|
@@ -1075,6 +1078,29 @@ VALUE rcsim_add_systemI_systemTs(VALUE mod, VALUE systemIV, VALUE sysVs) {
|
|
1075
1078
|
return systemIV;
|
1076
1079
|
}
|
1077
1080
|
|
1081
|
+
/* Adds sub signals a C signal. */
|
1082
|
+
VALUE rcsim_add_signal_signals(VALUE mod, VALUE signalIV, VALUE sigVs) {
|
1083
|
+
/* Get the C signal from the Ruby value. */
|
1084
|
+
SignalI signalI;
|
1085
|
+
value_to_rcsim(SignalIS,signalIV,signalI);
|
1086
|
+
// printf("rcsim_add_signal_signals with signalI=%p\n",signalI);
|
1087
|
+
/* Prepare the size for the alternate system types. */
|
1088
|
+
long num = RARRAY_LEN(sigVs);
|
1089
|
+
long old_num = signalI->num_signals;
|
1090
|
+
signalI->num_signals += num;
|
1091
|
+
signalI->signals=realloc(signalI->signals,
|
1092
|
+
sizeof(SignalI[signalI->num_signals]));
|
1093
|
+
// signalI->signals = (SignalI*)my_realloc(signalI->signals,
|
1094
|
+
// sizeof(SignalI[old_num]), sizeof(SignalI[signalI->num_signals]));
|
1095
|
+
/* Get and add the alternate system types from the Ruby value. */
|
1096
|
+
for(long i=0; i< num; ++i) {
|
1097
|
+
SignalI sig;
|
1098
|
+
value_to_rcsim(SignalIS,rb_ary_entry(sigVs,i),sig);
|
1099
|
+
signalI->signals[old_num + i] = sig;
|
1100
|
+
}
|
1101
|
+
return signalIV;
|
1102
|
+
}
|
1103
|
+
|
1078
1104
|
/* Adds arguments to a C print. */
|
1079
1105
|
VALUE rcsim_add_print_args(VALUE mod, VALUE printV, VALUE argVs) {
|
1080
1106
|
/* Get the C print from the Ruby value. */
|
@@ -1459,6 +1485,7 @@ void Init_hruby_sim() {
|
|
1459
1485
|
rb_define_singleton_method(mod,"rcsim_add_scope_scopes",rcsim_add_scope_scopes,2);
|
1460
1486
|
rb_define_singleton_method(mod,"rcsim_add_behavior_events",rcsim_add_behavior_events,2);
|
1461
1487
|
rb_define_singleton_method(mod,"rcsim_add_systemI_systemTs",rcsim_add_systemI_systemTs,2);
|
1488
|
+
rb_define_singleton_method(mod,"rcsim_add_signal_signals",rcsim_add_signal_signals,2);
|
1462
1489
|
rb_define_singleton_method(mod,"rcsim_add_print_args",rcsim_add_print_args,2);
|
1463
1490
|
rb_define_singleton_method(mod,"rcsim_add_hif_noifs",rcsim_add_hif_noifs,3);
|
1464
1491
|
rb_define_singleton_method(mod,"rcsim_add_hcase_whens",rcsim_add_hcase_whens,3);
|
data/ext/hruby_sim/hruby_sim.h
CHANGED
@@ -530,6 +530,9 @@ typedef struct SignalIS_ {
|
|
530
530
|
Value c_value; /* The current value of the signal. */
|
531
531
|
Value f_value; /* The future (next) value of the signal. */
|
532
532
|
|
533
|
+
int num_signals; /* The number of sub signals. */
|
534
|
+
SignalI* signals; /* The sub signals. */
|
535
|
+
|
533
536
|
int fading; /* Tell if the signal can be overwritten by Z. */
|
534
537
|
|
535
538
|
int num_any; /* The number of behavior activated on any edge. */
|
@@ -729,14 +729,26 @@ void transmit_to_signal_range_seq(Value value, RefRangeS ref) {
|
|
729
729
|
SignalI signal = ref.signal;
|
730
730
|
unsigned long long first = ref.first;
|
731
731
|
unsigned long long last = ref.last;
|
732
|
-
// printf("Tansmit to signal range: %s(%p) [%llu,%llu]\n",signal->name,signal,first,last);
|
732
|
+
// printf("Tansmit to signal range seq: %s(%p) [%llu,%llu]\n",signal->name,signal,first,last);
|
733
|
+
// /* Can transmit, copy the content. */
|
734
|
+
// if (signal->fading)
|
735
|
+
// // write_range(value,first,last,signal->f_value->type,signal->f_value);
|
736
|
+
// write_range(value,first,last,ref.type,signal->f_value);
|
737
|
+
// else
|
738
|
+
// // write_range_no_z(value,first,last,signal->f_value->type,signal->f_value);
|
739
|
+
// write_range_no_z(value,first,last,ref.type,signal->f_value);
|
740
|
+
/* The base type is stored here to avoid allocating a new type each time.
|
741
|
+
* It have an arbitrary base size a single element. */
|
742
|
+
static TypeS baseT = { 1, 1 };
|
743
|
+
baseT.base = signal->f_value->type->base;
|
744
|
+
// printf("Tansmit to signal range: %s(%p) [%lld:%lld]\n",signal->name,signal,first,last);
|
733
745
|
/* Can transmit, copy the content. */
|
734
746
|
if (signal->fading)
|
735
|
-
|
736
|
-
|
747
|
+
signal->f_value = write_range(value,first,last,&baseT,
|
748
|
+
signal->f_value);
|
737
749
|
else
|
738
|
-
|
739
|
-
|
750
|
+
signal->f_value = write_range_no_z(value,first,last,&baseT,
|
751
|
+
signal->f_value);
|
740
752
|
/* And touch the signal. */
|
741
753
|
touch_signal_seq(signal);
|
742
754
|
}
|
@@ -181,7 +181,7 @@ Value calc_expression(Expression expr, Value res) {
|
|
181
181
|
* @param behavior the behavior in execution. */
|
182
182
|
void execute_statement(Statement stmnt, int mode, Behavior behavior) {
|
183
183
|
/* Depending on the kind of statement. */
|
184
|
-
// printf("Executing statement=%p with kind=%d\n",stmnt,stmnt->kind);fflush(stdout);
|
184
|
+
// printf("Executing statement=%p with kind=%d in mode=%d\n",stmnt,stmnt->kind,mode);fflush(stdout);
|
185
185
|
switch(stmnt->kind) {
|
186
186
|
case TRANSMIT:
|
187
187
|
{
|
@@ -236,6 +236,7 @@ void execute_statement(Statement stmnt, int mode, Behavior behavior) {
|
|
236
236
|
lastV = calc_expression(refr->last,lastV);
|
237
237
|
long long last = value2integer(lastV);
|
238
238
|
free_value();
|
239
|
+
// printf("firstV=%lld lastV=%lld right=%lld mode=%d\n",firstV->data_int,lastV->data_int,right->data_int,mode);
|
239
240
|
/* Generate the reference inside the left value. */
|
240
241
|
RefRangeS ref =
|
241
242
|
make_ref_rangeS((SignalI)(refr->ref),refr->type,
|
@@ -399,9 +400,15 @@ void execute_statement(Statement stmnt, int mode, Behavior behavior) {
|
|
399
400
|
}
|
400
401
|
break;
|
401
402
|
}
|
403
|
+
case TIME_TERMINATE:
|
404
|
+
{
|
405
|
+
terminate();
|
406
|
+
break;
|
407
|
+
}
|
402
408
|
case BLOCK:
|
403
409
|
{
|
404
410
|
Block block = (Block)stmnt;
|
411
|
+
// printf("Block mode=%d\n",block->mode);
|
405
412
|
/* Execute each statement of the block. */
|
406
413
|
for(int i=0; i<block->num_stmnts; ++i)
|
407
414
|
execute_statement(block->stmnts[i],block->mode,behavior);
|
@@ -155,12 +155,28 @@ static void vcd_print_value(Value value) {
|
|
155
155
|
/** Prints a signal declaration.
|
156
156
|
* @param signal the signal to declare */
|
157
157
|
static void vcd_print_var(SignalI signal) {
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
158
|
+
if (signal->num_signals > 0) {
|
159
|
+
int i;
|
160
|
+
/* The signal is hierarchical, declare its sub signals. */
|
161
|
+
/* Declares the hierachical name. */
|
162
|
+
vcd_print("$scope module ");
|
163
|
+
vcd_print_name((Object)signal);
|
164
|
+
vcd_print(" $end\n");
|
165
|
+
/* Declare the inners of the systems. */
|
166
|
+
for(i=0; i<signal->num_signals; ++i) {
|
167
|
+
vcd_print_var(signal->signals[i]);
|
168
|
+
}
|
169
|
+
/* Close the hierarchy. */
|
170
|
+
vcd_print("$upscope $end\n");
|
171
|
+
} else {
|
172
|
+
/* The signal is flat, can declarate it directly. */
|
173
|
+
vcd_print("$var wire %d ",type_width(signal->type));
|
174
|
+
// vcd_print_full_name((Object)signal);
|
175
|
+
vcd_print_signal_id(signal);
|
176
|
+
vcd_print(" ");
|
177
|
+
vcd_print_name((Object)signal);
|
178
|
+
vcd_print(" $end\n");
|
179
|
+
}
|
164
180
|
}
|
165
181
|
|
166
182
|
|
@@ -180,7 +196,8 @@ static void vcd_print_signal_fvalue(SignalI signal) {
|
|
180
196
|
/** Prints a signal with its current value if any
|
181
197
|
* @param signal the signal to show */
|
182
198
|
static void vcd_print_signal_cvalue(SignalI signal) {
|
183
|
-
if (signal->c_value) {
|
199
|
+
if ((signal->num_signals == 0) && signal->c_value) {
|
200
|
+
/* The signal is not hierachical and has a current value. */
|
184
201
|
vcd_print_value(signal->c_value);
|
185
202
|
// vcd_print(" ");
|
186
203
|
// vcd_print_full_name((Object)signal);
|
@@ -63,8 +63,15 @@ void default_print_name(Object object) {
|
|
63
63
|
}
|
64
64
|
/* Depending on the kind of object. */
|
65
65
|
switch(object->kind) {
|
66
|
-
case SYSTEMT:
|
67
66
|
case SIGNALI:
|
67
|
+
/* Print the name if name. */
|
68
|
+
/* Trick: SystemT, SignalI, Scope and SystemI have the
|
69
|
+
* field name at the same place. */
|
70
|
+
if (((SignalI)object)->name != NULL) {
|
71
|
+
printf("%s",((SignalI)object)->name);
|
72
|
+
}
|
73
|
+
break;
|
74
|
+
case SYSTEMT:
|
68
75
|
case SCOPE:
|
69
76
|
case SYSTEMI:
|
70
77
|
/* Print the name if name. */
|
@@ -73,6 +80,7 @@ void default_print_name(Object object) {
|
|
73
80
|
if (((SystemI)object)->name != NULL) {
|
74
81
|
printf("%s",((SystemI)object)->name);
|
75
82
|
}
|
83
|
+
break;
|
76
84
|
default: /* Nothing to do */
|
77
85
|
break;
|
78
86
|
}
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
|
4
4
|
function :func do |addr|
|
5
|
-
bit[4][-4].constant tbl: [
|
5
|
+
bit[4][-4].constant tbl: [ _b1000, _b1001, _b1010, _b1011 ]
|
6
6
|
|
7
7
|
tbl[addr]
|
8
8
|
end
|
@@ -10,9 +10,11 @@ end
|
|
10
10
|
|
11
11
|
system :with_func do
|
12
12
|
[4].inner :addr, :val
|
13
|
+
# bit[4][-4].constant tbl: [ _b1000, _b1001, _b1010, _b1011 ]
|
13
14
|
|
14
15
|
val <= func(addr)
|
15
16
|
# val <= 1
|
17
|
+
# val <= tbl[addr]
|
16
18
|
|
17
19
|
timed do
|
18
20
|
addr <= 0
|
@@ -117,7 +117,7 @@ system :mei8 do |prog_file = "./prog.obj"|
|
|
117
117
|
# Format 1
|
118
118
|
entry("01oooyyy") { wf <= 1
|
119
119
|
# Destination is also y in case of inc/dec
|
120
|
-
hif (ir[6..4] ==
|
120
|
+
hif (ir[6..4] == _b101) { dst <= y }
|
121
121
|
alu.(o,a,src1) } # binary alu
|
122
122
|
# Format 1 extended.
|
123
123
|
entry("10000yyy") { wr <= 0; wf <= 1
|
@@ -128,17 +128,17 @@ system :mei8 do |prog_file = "./prog.obj"|
|
|
128
128
|
entry("10011yyy") { branch <= 1 # jr y, must inc y
|
129
129
|
alu.(2,src1) } # since pc-1 is used
|
130
130
|
# Format 2
|
131
|
-
entry("1010iiii") { alu.(7,[
|
131
|
+
entry("1010iiii") { alu.(7,[_b0000,i]) } # movl i
|
132
132
|
entry("1011iiii") { alu.(7,[i,a[3..0]]) } # movh i
|
133
133
|
# Format 4
|
134
134
|
entry("11110110") { branch <= 1 # trap
|
135
135
|
alu.(7,0xFC) }
|
136
|
-
entry("11110ooo") { wf <= 1; alu.([
|
136
|
+
entry("11110ooo") { wf <= 1; alu.([_b1,o],a) } # unary alu
|
137
137
|
entry("111110os") { st <= s; ld <= ~s # ++--ld / ++--st
|
138
|
-
alu.([
|
138
|
+
alu.([_b001,o],g); dst <= 6 }
|
139
139
|
entry("1111110i") { branch <= i
|
140
140
|
st <= ~i; ld <= i
|
141
|
-
alu.([
|
141
|
+
alu.([_b001,~i],h)
|
142
142
|
dst <= 7; io_out <= pc } # push / pop pc
|
143
143
|
# Format 3
|
144
144
|
entry("11cccsii") { branch <= cc; wr <= 0
|
@@ -180,7 +180,7 @@ system :mei8 do |prog_file = "./prog.obj"|
|
|
180
180
|
[a,b,c,d,e,f,g,h,zf,cf,sf,vf,nbr,npc,s].each { |r| r <= 0 }
|
181
181
|
end
|
182
182
|
# Ensures a is 0 and enable interrupts when starting.
|
183
|
-
helsif(init) { a<= 0; s <=
|
183
|
+
helsif(init) { a<= 0; s <= _b00000011; }
|
184
184
|
helsif(iq_calc) do
|
185
185
|
s[7] <= 1
|
186
186
|
hif(iq1) { s[1] <= 0 }
|
@@ -195,14 +195,14 @@ system :mei8 do |prog_file = "./prog.obj"|
|
|
195
195
|
zf <= alu.zf; cf <= alu.cf; sf <= alu.sf; vf <= alu.vf
|
196
196
|
end
|
197
197
|
# Specific cases
|
198
|
-
hif(ir ==
|
199
|
-
hif(ir ==
|
198
|
+
hif(ir == _b11110111) { s <= a; a <= s } # xs
|
199
|
+
hif(ir == _b11110110) { s[7] <= 1 } # trap
|
200
200
|
hif(branch) { npc <= alu.z; nbr <= 1 } # Branch
|
201
201
|
end
|
202
202
|
# Write memory read result to a register if any.
|
203
203
|
helsif (io_r_done) do
|
204
204
|
hif(branch) { npc <= data; nbr <= 1 } # pop case
|
205
|
-
helsif(ir[7..3] ==
|
205
|
+
helsif(ir[7..3] == _b10001) do # ld case
|
206
206
|
[a,b,c,d,e,f,g,h].hcase(dst) {|r| r <= data }
|
207
207
|
end
|
208
208
|
helse { a <= data } # ld++-- case
|
@@ -231,8 +231,8 @@ system :mei8 do |prog_file = "./prog.obj"|
|
|
231
231
|
goto(iq_chk,:iq_s) # Interrupt / No interrupt
|
232
232
|
goto(branch,:br) # Branch instruction
|
233
233
|
goto((ld|st) & ~io_done,:ld_st) # ld/st instruction
|
234
|
-
goto(ir ==
|
235
|
-
goto(ir ==
|
234
|
+
goto(ir == _b11111110,:ht) # Halt instruction
|
235
|
+
goto(ir == _b11111111,:re) } # Reset instruction
|
236
236
|
# Branch state.
|
237
237
|
state(:br) { goto(iq_chk,:iq_s,:fe) } # Interrupt / No interrupt
|
238
238
|
sync(:br) { hif(nbr) { pc <= npc-1 } } # Next pc is the branch target
|
@@ -119,7 +119,7 @@ system :mei8 do |prog_file = "./prog.obj"|
|
|
119
119
|
# Format 1
|
120
120
|
entry("01oooyyy") { wf <= 1
|
121
121
|
# Destination is also y in case of inc/dec
|
122
|
-
hif (ir[6..4] ==
|
122
|
+
hif (ir[6..4] == _b101) { dst <= y }
|
123
123
|
alu.(o,a,src1) } # binary alu
|
124
124
|
# Format 1 extended.
|
125
125
|
entry("10000yyy") { wr <= 0; wf <= 1
|
@@ -130,17 +130,17 @@ system :mei8 do |prog_file = "./prog.obj"|
|
|
130
130
|
entry("10011yyy") { branch <= 1 # jr y, must inc y
|
131
131
|
alu.(2,src1) } # since pc-1 is used
|
132
132
|
# Format 2
|
133
|
-
entry("1010iiii") { alu.(7,[
|
133
|
+
entry("1010iiii") { alu.(7,[_b0000,i]) } # movl i
|
134
134
|
entry("1011iiii") { alu.(7,[i,a[3..0]]) } # movh i
|
135
135
|
# Format 4
|
136
136
|
entry("11110110") { branch <= 1 # trap
|
137
137
|
alu.(7,0xFC) }
|
138
|
-
entry("11110ooo") { wf <= 1; alu.([
|
138
|
+
entry("11110ooo") { wf <= 1; alu.([_b1,o],a) } # unary alu
|
139
139
|
entry("111110os") { st <= s; ld <= ~s # ++--ld / ++--st
|
140
|
-
alu.([
|
140
|
+
alu.([_b001,o],g); dst <= 6 }
|
141
141
|
entry("1111110i") { branch <= i
|
142
142
|
st <= ~i; ld <= i
|
143
|
-
alu.([
|
143
|
+
alu.([_b001,~i],h)
|
144
144
|
dst <= 7; io_out <= pc } # push / pop pc
|
145
145
|
# Format 3
|
146
146
|
entry("11cccsii") { branch <= cc; wr <= 0
|
@@ -182,7 +182,7 @@ system :mei8 do |prog_file = "./prog.obj"|
|
|
182
182
|
[a,b,c,d,e,f,g,h,zf,cf,sf,vf,nbr,npc,s].each { |r| r <= 0 }
|
183
183
|
end
|
184
184
|
# Ensures a is 0 and enable interrupts when starting.
|
185
|
-
helsif(init) { a<= 0; s <=
|
185
|
+
helsif(init) { a<= 0; s <= _b00000011; }
|
186
186
|
helsif(iq_calc) do
|
187
187
|
s[7] <= 1
|
188
188
|
hif(iq1) { s[1] <= 0 }
|
@@ -197,14 +197,14 @@ system :mei8 do |prog_file = "./prog.obj"|
|
|
197
197
|
zf <= alu.zf; cf <= alu.cf; sf <= alu.sf; vf <= alu.vf
|
198
198
|
end
|
199
199
|
# Specific cases
|
200
|
-
hif(ir ==
|
201
|
-
hif(ir ==
|
200
|
+
hif(ir == _b11110111) { s <= a; a <= s } # xs
|
201
|
+
hif(ir == _b11110110) { s[7] <= 1 } # trap
|
202
202
|
hif(branch) { npc <= alu.z; nbr <= 1 } # Branch
|
203
203
|
end
|
204
204
|
# Write memory read result to a register if any.
|
205
205
|
helsif (io_r_done) do
|
206
206
|
hif(branch) { npc <= data; nbr <= 1 } # pop case
|
207
|
-
helsif(ir[7..3] ==
|
207
|
+
helsif(ir[7..3] == _b10001) do # ld case
|
208
208
|
[a,b,c,d,e,f,g,h].hcase(dst) {|r| r <= data }
|
209
209
|
end
|
210
210
|
helse { a <= data } # ld++-- case
|
@@ -233,8 +233,8 @@ system :mei8 do |prog_file = "./prog.obj"|
|
|
233
233
|
goto(iq_chk,:iq_s) # Interrupt / No interrupt
|
234
234
|
goto(branch,:br) # Branch instruction
|
235
235
|
goto((ld|st) & ~io_done,:ld_st) # ld/st instruction
|
236
|
-
goto(ir ==
|
237
|
-
goto(ir ==
|
236
|
+
goto(ir == _b11111110,:ht) # Halt instruction
|
237
|
+
goto(ir == _b11111111,:re) } # Reset instruction
|
238
238
|
# Branch state.
|
239
239
|
state(:br) { goto(iq_chk,:iq_s,:fe) } # Interrupt / No interrupt
|
240
240
|
sync(:br) { hif(nbr) { pc <= npc-1 } } # Next pc is the branch target
|
@@ -42,15 +42,15 @@ system :neg_arith_bench do
|
|
42
42
|
z <= x * y
|
43
43
|
cmp <= (x < y)
|
44
44
|
!10.ns
|
45
|
-
x <=
|
46
|
-
y <=
|
45
|
+
x <= _b000000011010
|
46
|
+
y <= _b000011111010
|
47
47
|
z <= 0
|
48
48
|
!10.ns
|
49
49
|
z <= x * y
|
50
50
|
cmp <= (x < y)
|
51
51
|
!10.ns
|
52
|
-
x <=
|
53
|
-
y <=
|
52
|
+
x <= _b000000011010
|
53
|
+
y <= _b111111111010
|
54
54
|
z <= 0
|
55
55
|
!10.ns
|
56
56
|
z <= x * y
|
@@ -50,13 +50,13 @@ system :work do
|
|
50
50
|
|
51
51
|
# The input memory.
|
52
52
|
mem_rom([8],8,clk,rst,
|
53
|
-
[
|
54
|
-
|
53
|
+
[_b00000001,_b00000010,_b00000011,_b00000100,
|
54
|
+
_b00000101,_b00000110,_b00000111,_b00001000]).(:iMem)
|
55
55
|
# The output memory.
|
56
56
|
mem_dual([8],8,clk,rst).(:oMem)
|
57
57
|
# The coefficients.
|
58
|
-
coefs = [
|
59
|
-
|
58
|
+
coefs = [_b11001100,_b00110011,_b10101010,_b01010101,
|
59
|
+
_b11110000,_b00001111,_b11100011,_b00011100]
|
60
60
|
|
61
61
|
# The filter
|
62
62
|
fir([8],iMem.branch(:rinc),oMem.branch(:winc),coefs).(:my_fir).(clk,rst,req,ack)
|