HDLRuby 2.11.3 → 2.11.4
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 +6 -2
- data/ext/hruby_sim/hruby_rcsim_build.c +33 -11
- data/ext/hruby_sim/hruby_sim.h +11 -1
- data/ext/hruby_sim/hruby_sim_tree_calc.c +14 -0
- data/lib/HDLRuby/hdr_samples/repeat_bench.rb +48 -0
- data/lib/HDLRuby/hruby_high.rb +11 -6
- data/lib/HDLRuby/hruby_low.rb +27 -17
- data/lib/HDLRuby/hruby_low2c.rb +26 -7
- data/lib/HDLRuby/hruby_rcsim.rb +16 -2
- data/lib/HDLRuby/hruby_rsim.rb +10 -1
- data/lib/HDLRuby/hruby_rsim_vcd.rb +15 -0
- data/lib/HDLRuby/hruby_verilog.rb +71 -58
- data/lib/HDLRuby/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b3303f28a79a14a42fb2421335afdbaa40c148440e622edaca2f8a98804192d
|
4
|
+
data.tar.gz: 12dd7c5fd160141c151db950b7d797ef53bf012549ef983f8cf1b648edb3a85e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94ba5098e5e8003f64c53f86ba47f8e831e3e49d39aa4f8991f3595dfec560749079720a6602bf76f2e31eacf88c922a0c689bf575e2ec17a48256dba70010d0
|
7
|
+
data.tar.gz: 1856330cc10987e979ed13211d3a6aaaa1f382bfe9a6831a4a235eac35ea912844c5ca9b667f2a899b87a47518c29e38cb8c9b7c6a5ee27e953872fb810b8f30
|
data/README.md
CHANGED
@@ -1949,15 +1949,19 @@ There are two kinds of such statements:
|
|
1949
1949
|
!10.ns
|
1950
1950
|
```
|
1951
1951
|
|
1952
|
-
- The `repeat` statements: such a statement takes as argument a
|
1952
|
+
- The `repeat` statements: such a statement takes as argument a number of iteration and a block. The execution of the block is repeated the given number times. For example, the following code executes 10 times the inversion of the `clk` signal every 10 nanoseconds:
|
1953
1953
|
|
1954
1954
|
```ruby
|
1955
|
-
repeat(10
|
1955
|
+
repeat(10) do
|
1956
1956
|
!10.ns
|
1957
1957
|
clk <= ~clk
|
1958
1958
|
end
|
1959
1959
|
```
|
1960
1960
|
|
1961
|
+
__Note:__
|
1962
|
+
|
1963
|
+
This statement is not synthesizable and therefore can only be used in timed behaviors.
|
1964
|
+
|
1961
1965
|
### Parallel and sequential execution
|
1962
1966
|
|
1963
1967
|
Time behaviors are by default sequential, but they can include both parallel and
|
@@ -430,6 +430,27 @@ VALUE rcsim_make_timeWait(VALUE mod, VALUE unitV, VALUE delayV) {
|
|
430
430
|
return res;
|
431
431
|
}
|
432
432
|
|
433
|
+
/* Creating a time repeat C object. */
|
434
|
+
VALUE rcsim_make_timeRepeat(VALUE mod, VALUE numberV, VALUE statementV) {
|
435
|
+
// printf("rcsim_make_timeRepeat\n"); fflush(stdout);
|
436
|
+
/* Allocates the time repeat. */
|
437
|
+
TimeRepeat timeRepeat = (TimeRepeat)malloc(sizeof(TimeRepeatS));
|
438
|
+
// printf("timeRepeat=%p\n",timeRepeat); fflush(stdout);
|
439
|
+
/* Set it up. */
|
440
|
+
timeRepeat->kind = TIME_REPEAT;
|
441
|
+
/* Get and set the number of repeatition. */
|
442
|
+
long long number;
|
443
|
+
number = NUM2LL(numberV);
|
444
|
+
// printf("number=%lld\n",number); fflush(stdout);
|
445
|
+
timeRepeat->number = number;
|
446
|
+
/* Get and set the statement. */
|
447
|
+
value_to_rcsim(StatementS,statementV,timeRepeat->statement);
|
448
|
+
/* Returns the C time wait embedded into a ruby VALUE. */
|
449
|
+
VALUE res;
|
450
|
+
rcsim_to_value(TimeRepeatS,timeRepeat,res);
|
451
|
+
return res;
|
452
|
+
}
|
453
|
+
|
433
454
|
|
434
455
|
/* Creating a time terminate C object. */
|
435
456
|
VALUE rcsim_make_timeTerminate(VALUE mod) {
|
@@ -447,19 +468,19 @@ VALUE rcsim_make_timeTerminate(VALUE mod) {
|
|
447
468
|
|
448
469
|
|
449
470
|
/* Creating a hardware if C object. */
|
450
|
-
VALUE rcsim_make_hif(VALUE mod, VALUE
|
471
|
+
VALUE rcsim_make_hif(VALUE mod, VALUE conditionV, VALUE yesV, VALUE noV) {
|
451
472
|
// printf("rcsim_make_hif\n");
|
452
473
|
/* Allocates the hardware if. */
|
453
474
|
HIf hif = (HIf)malloc(sizeof(HIfS));
|
454
475
|
// printf("hif=%p\n",hif);
|
455
476
|
/* Set it up. */
|
456
477
|
hif->kind = HIF;
|
457
|
-
value_to_rcsim(ExpressionS,
|
458
|
-
value_to_rcsim(StatementS,
|
459
|
-
if (TYPE(
|
478
|
+
value_to_rcsim(ExpressionS,conditionV,hif->condition);
|
479
|
+
value_to_rcsim(StatementS,yesV,hif->yes);
|
480
|
+
if (TYPE(noV) == T_NIL)
|
460
481
|
hif->no = NULL;
|
461
482
|
else
|
462
|
-
value_to_rcsim(StatementS,
|
483
|
+
value_to_rcsim(StatementS,noV,hif->no);
|
463
484
|
hif->num_noifs = 0;
|
464
485
|
hif->noconds = NULL;
|
465
486
|
hif->nostmnts = NULL;
|
@@ -471,21 +492,21 @@ VALUE rcsim_make_hif(VALUE mod, VALUE condition, VALUE yes, VALUE no) {
|
|
471
492
|
|
472
493
|
|
473
494
|
/* Creating a hardware case C object. */
|
474
|
-
VALUE rcsim_make_hcase(VALUE mod, VALUE
|
495
|
+
VALUE rcsim_make_hcase(VALUE mod, VALUE valueV, VALUE defoltV) {
|
475
496
|
// printf("rcsim_make_hcase\n");
|
476
497
|
/* Allocates the hardware case. */
|
477
498
|
HCase hcase = (HCase)malloc(sizeof(HCaseS));
|
478
499
|
// printf("hcase=%p\n",hcase);
|
479
500
|
/* Set it up. */
|
480
501
|
hcase->kind = HCASE;
|
481
|
-
value_to_rcsim(ExpressionS,
|
502
|
+
value_to_rcsim(ExpressionS,valueV,hcase->value);
|
482
503
|
hcase->num_whens = 0;
|
483
504
|
hcase->matches = NULL;
|
484
505
|
hcase->stmnts = NULL;
|
485
|
-
if (TYPE(
|
506
|
+
if (TYPE(defoltV) == T_NIL)
|
486
507
|
hcase->defolt = NULL;
|
487
508
|
else
|
488
|
-
value_to_rcsim(StatementS,
|
509
|
+
value_to_rcsim(StatementS,defoltV,hcase->defolt);
|
489
510
|
/* Returns the C hardware case embedded into a ruby VALUE. */
|
490
511
|
VALUE res;
|
491
512
|
rcsim_to_value(HCaseS,hcase,res);
|
@@ -494,7 +515,7 @@ VALUE rcsim_make_hcase(VALUE mod, VALUE value, VALUE defolt) {
|
|
494
515
|
|
495
516
|
|
496
517
|
/* Creating a block C object. */
|
497
|
-
VALUE rcsim_make_block(VALUE mod, VALUE
|
518
|
+
VALUE rcsim_make_block(VALUE mod, VALUE modeV) {
|
498
519
|
// printf("rcsim_make_block\n");
|
499
520
|
/* Allocates the block. */
|
500
521
|
Block block = (Block)malloc(sizeof(BlockS));
|
@@ -507,7 +528,7 @@ VALUE rcsim_make_block(VALUE mod, VALUE mode) {
|
|
507
528
|
block->inners = NULL;
|
508
529
|
block->num_stmnts = 0;
|
509
530
|
block->stmnts = NULL;
|
510
|
-
block->mode = SYM2ID(
|
531
|
+
block->mode = SYM2ID(modeV) == id_PAR ? PAR : SEQ;
|
511
532
|
/* Returns the C block embedded into a ruby VALUE. */
|
512
533
|
VALUE res;
|
513
534
|
rcsim_to_value(BlockS,block,res);
|
@@ -1373,6 +1394,7 @@ void Init_hruby_sim() {
|
|
1373
1394
|
rb_define_singleton_method(mod,"rcsim_make_transmit",rcsim_make_transmit,2);
|
1374
1395
|
rb_define_singleton_method(mod,"rcsim_make_print",rcsim_make_print,0);
|
1375
1396
|
rb_define_singleton_method(mod,"rcsim_make_timeWait",rcsim_make_timeWait,2);
|
1397
|
+
rb_define_singleton_method(mod,"rcsim_make_timeRepeat",rcsim_make_timeRepeat,2);
|
1376
1398
|
rb_define_singleton_method(mod,"rcsim_make_timeTerminate",rcsim_make_timeTerminate,0);
|
1377
1399
|
rb_define_singleton_method(mod,"rcsim_make_hif",rcsim_make_hif,3);
|
1378
1400
|
rb_define_singleton_method(mod,"rcsim_make_hcase",rcsim_make_hcase,2);
|
data/ext/hruby_sim/hruby_sim.h
CHANGED
@@ -28,6 +28,7 @@ typedef struct PrintS_ PrintS;
|
|
28
28
|
typedef struct HIfS_ HIfS;
|
29
29
|
typedef struct HCaseS_ HCaseS;
|
30
30
|
typedef struct TimeWaitS_ TimeWaitS;
|
31
|
+
typedef struct TimeRepeatS_ TimeRepeatS;
|
31
32
|
typedef struct TimeTerminateS_ TimeTerminateS;
|
32
33
|
typedef struct ExpressionS_ ExpressionS;
|
33
34
|
typedef struct UnaryS_ UnaryS;
|
@@ -63,6 +64,7 @@ typedef struct PrintS_* Print;
|
|
63
64
|
typedef struct HIfS_* HIf;
|
64
65
|
typedef struct HCaseS_* HCase;
|
65
66
|
typedef struct TimeWaitS_* TimeWait;
|
67
|
+
typedef struct TimeRepeatS_* TimeRepeat;
|
66
68
|
typedef struct TimeTerminateS_* TimeTerminate;
|
67
69
|
typedef struct ExpressionS_* Expression;
|
68
70
|
typedef struct UnaryS_* Unary;
|
@@ -89,7 +91,8 @@ typedef enum {
|
|
89
91
|
#endif
|
90
92
|
OBJECT, SYSTEMT, SIGNALI, SCOPE, BEHAVIOR, SYSTEMI, CODE, BLOCK, EVENT,
|
91
93
|
#ifdef RCSIM
|
92
|
-
/* Statements */ TRANSMIT, PRINT, HIF, HCASE,
|
94
|
+
/* Statements */ TRANSMIT, PRINT, HIF, HCASE,
|
95
|
+
TIME_WAIT, TIME_REPEAT, TIME_TERMINATE,
|
93
96
|
/* Expressions */ UNARY, BINARY, SELECT, CONCAT, CAST,
|
94
97
|
/* References */ REF_OBJECT, REF_INDEX, REF_RANGE, REF_CONCAT,
|
95
98
|
/* Non-hardware*/ STRINGE,
|
@@ -670,6 +673,13 @@ typedef struct TimeWaitS_ {
|
|
670
673
|
unsigned long long delay; /* The delay to wait in pico seconds. */
|
671
674
|
} TimeWaitS;
|
672
675
|
|
676
|
+
/** The C model of a time repeat statement. */
|
677
|
+
typedef struct TimeRepeatS_ {
|
678
|
+
Kind kind; /* The kind of object. */
|
679
|
+
long long number; /* The number of interations, negative means infinity. */
|
680
|
+
Statement statement;/* The statement to execute in loop. */
|
681
|
+
} TimeRepeatS;
|
682
|
+
|
673
683
|
/** The C model of a time terminate statement. */
|
674
684
|
typedef struct TimeTerminateS_ {
|
675
685
|
Kind kind; /* The kind of object. */
|
@@ -358,6 +358,20 @@ void execute_statement(Statement stmnt, int mode, Behavior behavior) {
|
|
358
358
|
hw_wait(delay,behavior);
|
359
359
|
break;
|
360
360
|
}
|
361
|
+
case TIME_REPEAT:
|
362
|
+
{
|
363
|
+
TimeRepeat rep = (TimeRepeat)stmnt;
|
364
|
+
if (rep->number>=0) {
|
365
|
+
for(long long i=0; i<rep->number; ++i) {
|
366
|
+
execute_statement(rep->statement,mode,behavior);
|
367
|
+
}
|
368
|
+
} else {
|
369
|
+
for(;;) {
|
370
|
+
execute_statement(rep->statement,mode,behavior);
|
371
|
+
}
|
372
|
+
}
|
373
|
+
break;
|
374
|
+
}
|
361
375
|
case BLOCK:
|
362
376
|
{
|
363
377
|
Block block = (Block)stmnt;
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# A simple D-FF
|
2
|
+
system :dff do
|
3
|
+
input :d, :clk, :rst
|
4
|
+
output :q
|
5
|
+
|
6
|
+
(q <= d & ~rst).at(clk.posedge)
|
7
|
+
end
|
8
|
+
|
9
|
+
# A benchmark for the dff using repeat.
|
10
|
+
system :dff_bench do
|
11
|
+
inner :d, :clk, :rst
|
12
|
+
inner :q
|
13
|
+
|
14
|
+
dff(:my_dff).(d,clk,rst,q)
|
15
|
+
|
16
|
+
timed do
|
17
|
+
clk <= 0
|
18
|
+
rst <= 0
|
19
|
+
d <= _z
|
20
|
+
!10.ns
|
21
|
+
clk <= 1
|
22
|
+
rst <= 0
|
23
|
+
d <= _z
|
24
|
+
!10.ns
|
25
|
+
clk <= 0
|
26
|
+
rst <= 1
|
27
|
+
d <= _z
|
28
|
+
!10.ns
|
29
|
+
clk <= 1
|
30
|
+
rst <= 1
|
31
|
+
d <= _z
|
32
|
+
!10.ns
|
33
|
+
clk <= 0
|
34
|
+
rst <= 0
|
35
|
+
d <= 1
|
36
|
+
!10.ns
|
37
|
+
clk <= 1
|
38
|
+
rst <= 0
|
39
|
+
!10.ns
|
40
|
+
repeat(100) do
|
41
|
+
clk <= 0
|
42
|
+
d <= ~d
|
43
|
+
!10.ns
|
44
|
+
clk <= 1
|
45
|
+
!10.ns
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/HDLRuby/hruby_high.rb
CHANGED
@@ -2682,10 +2682,10 @@ module HDLRuby::High
|
|
2682
2682
|
|
2683
2683
|
# Converts the repeat statement to HDLRuby::Low.
|
2684
2684
|
def to_low
|
2685
|
-
#
|
2685
|
+
# timeRepeatL = HDLRuby::Low::TimeRepeat.new(self.statement.to_low,
|
2686
2686
|
# self.delay.to_low)
|
2687
|
-
timeRepeatL = HDLRuby::Low::TimeRepeat.new(self.
|
2688
|
-
|
2687
|
+
timeRepeatL = HDLRuby::Low::TimeRepeat.new(self.number,
|
2688
|
+
self.statement.to_low)
|
2689
2689
|
# # For debugging: set the source high object
|
2690
2690
|
# timeRepeatL.properties[:low2high] = self.hdr_id
|
2691
2691
|
# self.properties[:high2low] = timeRepeatL
|
@@ -4233,15 +4233,20 @@ module HDLRuby::High
|
|
4233
4233
|
self.add_statement(TimeWait.new(delay))
|
4234
4234
|
end
|
4235
4235
|
|
4236
|
-
# Adds a loop until +delay+ statement in the block in +mode+ whose
|
4236
|
+
# # Adds a loop until +delay+ statement in the block in +mode+ whose
|
4237
|
+
# # loop content is built using +ruby_block+.
|
4238
|
+
# def repeat(delay, mode = nil, &ruby_block)
|
4239
|
+
# Adds a +number+ times loop statement in the block in +mode+ whose
|
4237
4240
|
# loop content is built using +ruby_block+.
|
4238
|
-
|
4241
|
+
# NOTE: if +number+ is negative, the number of iteration is infinite.
|
4242
|
+
def repeat(number = -1, mode = nil, &ruby_block)
|
4239
4243
|
# Ensure there is a block.
|
4240
4244
|
ruby_block = proc {} unless block_given?
|
4241
4245
|
# Build the content block.
|
4242
4246
|
content = High.make_block(mode,&ruby_block)
|
4243
4247
|
# Create and add the statement.
|
4244
|
-
self.add_statement(TimeRepeat.new(content,delay))
|
4248
|
+
# self.add_statement(TimeRepeat.new(content,delay))
|
4249
|
+
self.add_statement(TimeRepeat.new(number,content))
|
4245
4250
|
end
|
4246
4251
|
|
4247
4252
|
# Converts the time block to HDLRuby::Low.
|
data/lib/HDLRuby/hruby_low.rb
CHANGED
@@ -4042,15 +4042,20 @@ module HDLRuby::Low
|
|
4042
4042
|
##
|
4043
4043
|
# Describes a timed loop statement: not synthesizable!
|
4044
4044
|
class TimeRepeat < Statement
|
4045
|
-
# The delay until the loop is repeated
|
4046
|
-
attr_reader :delay
|
4045
|
+
# # The delay until the loop is repeated
|
4046
|
+
# attr_reader :delay
|
4047
|
+
# The number of interrations.
|
4048
|
+
attr_reader :number
|
4047
4049
|
|
4048
4050
|
# The statement to execute.
|
4049
4051
|
attr_reader :statement
|
4050
4052
|
|
4051
|
-
# Creates a new timed loop statement execute in a loop +statement+ until
|
4052
|
-
# +delay+ has passed.
|
4053
|
-
def initialize(statement,delay)
|
4053
|
+
# # Creates a new timed loop statement execute in a loop +statement+ until
|
4054
|
+
# # +delay+ has passed.
|
4055
|
+
# def initialize(statement,delay)
|
4056
|
+
# Creates a new timed loop statement execute in a loop +statement+
|
4057
|
+
# +number+ times (negative means inifinity).
|
4058
|
+
def initialize(number,statement)
|
4054
4059
|
# Check and set the statement.
|
4055
4060
|
unless statement.is_a?(Statement)
|
4056
4061
|
raise AnyError,
|
@@ -4061,13 +4066,15 @@ module HDLRuby::Low
|
|
4061
4066
|
# And set its parent.
|
4062
4067
|
statement.parent = self
|
4063
4068
|
|
4064
|
-
# Check and set the delay.
|
4065
|
-
unless delay.is_a?(Delay)
|
4066
|
-
|
4067
|
-
end
|
4068
|
-
@delay = delay
|
4069
|
-
#
|
4070
|
-
|
4069
|
+
# # Check and set the delay.
|
4070
|
+
# unless delay.is_a?(Delay)
|
4071
|
+
# raise AnyError, "Invalid class for a delay: #{delay.class}."
|
4072
|
+
# end
|
4073
|
+
# @delay = delay
|
4074
|
+
# Check and set the number.
|
4075
|
+
@number = number.to_i
|
4076
|
+
# # And set its parent.
|
4077
|
+
# delay.parent = self
|
4071
4078
|
end
|
4072
4079
|
|
4073
4080
|
# Iterates over each object deeply.
|
@@ -4080,26 +4087,29 @@ module HDLRuby::Low
|
|
4080
4087
|
ruby_block.call(self)
|
4081
4088
|
# Then apply on the statement.
|
4082
4089
|
self.statement.each_deep(&ruby_block)
|
4083
|
-
# Then apply on the delay.
|
4084
|
-
self.delay.each_deep(&ruby_block)
|
4090
|
+
# # Then apply on the delay.
|
4091
|
+
# self.delay.each_deep(&ruby_block)
|
4085
4092
|
end
|
4086
4093
|
|
4087
4094
|
# Comparison for hash: structural comparison.
|
4088
4095
|
def eql?(obj)
|
4089
4096
|
return false unless obj.is_a?(TimeRepeat)
|
4090
|
-
return false unless @delay.eql?(obj.delay)
|
4097
|
+
# return false unless @delay.eql?(obj.delay)
|
4098
|
+
return false unless @number.eql?(obj.number)
|
4091
4099
|
return false unless @statement.eql?(obj.statement)
|
4092
4100
|
return true
|
4093
4101
|
end
|
4094
4102
|
|
4095
4103
|
# Hash function.
|
4096
4104
|
def hash
|
4097
|
-
return [@delay,@statement].hash
|
4105
|
+
# return [@delay,@statement].hash
|
4106
|
+
return [@number,@statement].hash
|
4098
4107
|
end
|
4099
4108
|
|
4100
4109
|
# Clones the TimeRepeat (deeply)
|
4101
4110
|
def clone
|
4102
|
-
return TimeRepeat.new(@statement.clone,@delay.clone)
|
4111
|
+
# return TimeRepeat.new(@statement.clone,@delay.clone)
|
4112
|
+
return TimeRepeat.new(@statement.clone,@number)
|
4103
4113
|
end
|
4104
4114
|
|
4105
4115
|
# Iterates over the expression children if any.
|
data/lib/HDLRuby/hruby_low2c.rb
CHANGED
@@ -1803,20 +1803,39 @@ module HDLRuby::Low
|
|
1803
1803
|
## Extends the TimeRepeat class with generation of C text.
|
1804
1804
|
class TimeRepeat
|
1805
1805
|
|
1806
|
+
# # Generates the C text of the equivalent HDLRuby code.
|
1807
|
+
# # +level+ is the hierachical level of the object.
|
1808
|
+
# # def to_c(level = 0)
|
1809
|
+
# def to_c(res,level = 0)
|
1810
|
+
# # The resulting string.
|
1811
|
+
# # res = " " * level*3
|
1812
|
+
# res << " " * level*3
|
1813
|
+
# # Generate an infinite loop executing the block and waiting.
|
1814
|
+
# res << "for(;;) {\n"
|
1815
|
+
# # res << "#{self.statement.to_c(level+1)}\n"
|
1816
|
+
# self.statement.to_c(res,level+1)
|
1817
|
+
# res << "\n"
|
1818
|
+
# res << " " * (level+1)*3
|
1819
|
+
# res << Low2C.wait_code(self,level)
|
1820
|
+
# # Return the resulting string.
|
1821
|
+
# return res
|
1822
|
+
# end
|
1823
|
+
|
1806
1824
|
# Generates the C text of the equivalent HDLRuby code.
|
1807
1825
|
# +level+ is the hierachical level of the object.
|
1808
1826
|
# def to_c(level = 0)
|
1809
1827
|
def to_c(res,level = 0)
|
1810
1828
|
# The resulting string.
|
1811
|
-
# res = " " * level*3
|
1812
1829
|
res << " " * level*3
|
1813
|
-
|
1814
|
-
|
1815
|
-
|
1830
|
+
if (number < 0) then
|
1831
|
+
# Generate an infinite loop executing the block and waiting.
|
1832
|
+
res << "for(;;) {\n"
|
1833
|
+
else
|
1834
|
+
# Generate a finite loop.
|
1835
|
+
res << "for(long long i = 0; i<#{self.number}; ++i) {\n"
|
1836
|
+
end
|
1816
1837
|
self.statement.to_c(res,level+1)
|
1817
|
-
res << "\n"
|
1818
|
-
res << " " * (level+1)*3
|
1819
|
-
res << Low2C.wait_code(self,level)
|
1838
|
+
res << " " * level*3 << "}\n"
|
1820
1839
|
# Return the resulting string.
|
1821
1840
|
return res
|
1822
1841
|
end
|
data/lib/HDLRuby/hruby_rcsim.rb
CHANGED
@@ -654,7 +654,21 @@ module HDLRuby::High
|
|
654
654
|
## Extends the TimeRepeat class for hybrid Ruby-C simulation.
|
655
655
|
class TimeRepeat
|
656
656
|
attr_reader :rcstatement
|
657
|
-
|
657
|
+
|
658
|
+
# Generate the C description of the hardware case.
|
659
|
+
# +owner+ is a link to the C description of the owner behavior if any.
|
660
|
+
def to_rcsim(owner = nil)
|
661
|
+
# Create the timeRepeat C object.
|
662
|
+
@rcstatement = RCSim.rcsim_make_timeRepeat(self.number,
|
663
|
+
self.statement.to_rcsim)
|
664
|
+
|
665
|
+
# Sets the owner if any.
|
666
|
+
if owner then
|
667
|
+
RCSim.rcsim_set_owner(@rcstatement,owner)
|
668
|
+
end
|
669
|
+
|
670
|
+
return @rcstatement
|
671
|
+
end
|
658
672
|
end
|
659
673
|
|
660
674
|
|
@@ -670,7 +684,7 @@ module HDLRuby::High
|
|
670
684
|
|
671
685
|
# Sets the owner if any.
|
672
686
|
if owner then
|
673
|
-
RCSim.
|
687
|
+
RCSim.rcsim_set_owner(@rcstatement,owner)
|
674
688
|
end
|
675
689
|
|
676
690
|
# Add the inner signals.
|
data/lib/HDLRuby/hruby_rsim.rb
CHANGED
@@ -701,7 +701,16 @@ module HDLRuby::High
|
|
701
701
|
##
|
702
702
|
# Describes a timed loop statement: not synthesizable!
|
703
703
|
class TimeRepeat
|
704
|
-
##
|
704
|
+
## Initialize the simulation for system +systemT+.
|
705
|
+
def init_sim(systemT)
|
706
|
+
# Recurde on the statement.
|
707
|
+
self.statement.init_sim(systemT)
|
708
|
+
end
|
709
|
+
|
710
|
+
## Executes the statement.
|
711
|
+
def execute(mode)
|
712
|
+
self.number.times { self.statement.execute(mode) }
|
713
|
+
end
|
705
714
|
end
|
706
715
|
|
707
716
|
|
@@ -179,6 +179,21 @@ module HDLRuby::High
|
|
179
179
|
end
|
180
180
|
end
|
181
181
|
|
182
|
+
##
|
183
|
+
# Enhance the TimeRepeat class with VCD support.
|
184
|
+
class TimeRepeat
|
185
|
+
## Shows the hierarchy of the variables.
|
186
|
+
def show_hierarchy(vcdout)
|
187
|
+
# Recurse on the statement.
|
188
|
+
self.statement.show_hierarchy(vcdout)
|
189
|
+
end
|
190
|
+
|
191
|
+
## Gets the VCD variables with their long name.
|
192
|
+
def get_vars_with_fullname(vars_with_fullname = {})
|
193
|
+
# By default: nothing to do
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
182
197
|
##
|
183
198
|
# Enhance the TimeWait class with VCD support.
|
184
199
|
class TimeWait
|
@@ -254,60 +254,62 @@ module HDLRuby::Low
|
|
254
254
|
|
255
255
|
|
256
256
|
|
257
|
-
#
|
258
|
-
#
|
259
|
-
#
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
end
|
257
|
+
# Deprecated with new TimeRepeat!
|
258
|
+
#
|
259
|
+
# # Extract and convert to verilog the TimeRepeat statements.
|
260
|
+
# # NOTE: work only on the current level of the block (should be called
|
261
|
+
# # through each_block_deep).
|
262
|
+
# def repeat_to_verilog!
|
263
|
+
# code = ""
|
264
|
+
# # Gather the TimeRepeat statements.
|
265
|
+
# repeats = self.each_statement.find_all { |st| st.is_a?(TimeRepeat) }
|
266
|
+
# # Remove them from the block.
|
267
|
+
# repeats.each { |st| self.delete_statement!(st) }
|
268
|
+
# # Generate them separately in timed always processes.
|
269
|
+
# repeats.each do |st|
|
270
|
+
# code << " always #{st.delay.to_verilog} begin\n"
|
271
|
+
|
272
|
+
# # Perform "scheduling" using the method "flatten".
|
273
|
+
# block = st.statement.flatten(st.statement.mode.to_s)
|
274
|
+
|
275
|
+
# # Declaration of "inner" part within "always".
|
276
|
+
# block.each_inner do |inner|
|
277
|
+
# # if regs.include?(inner.name) then
|
278
|
+
# if HDLRuby::Low::VERILOG_REGS.include?(inner.to_verilog) then
|
279
|
+
# code << " reg"
|
280
|
+
# else
|
281
|
+
# code << " wire"
|
282
|
+
# end
|
283
|
+
|
284
|
+
# # Variable has "base", but if there is width etc, it is not in "base".
|
285
|
+
# # It is determined by an if.
|
286
|
+
# if inner.type.base?
|
287
|
+
# if inner.type.base.base?
|
288
|
+
# code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog}"
|
289
|
+
# else
|
290
|
+
# code << "#{inner.type.to_verilog} #{inner.to_verilog}"
|
291
|
+
# end
|
292
|
+
# else
|
293
|
+
# code << " #{inner.type.to_verilog}#{inner.to_verilog}"
|
294
|
+
# end
|
295
|
+
# if inner.value then
|
296
|
+
# # There is an initial value.
|
297
|
+
# code << " = #{inner.value.to_verilog}"
|
298
|
+
# end
|
299
|
+
# code << ";\n"
|
300
|
+
# end
|
301
|
+
|
302
|
+
# # Translate the block that finished scheduling.
|
303
|
+
# block.each_statement do |statement|
|
304
|
+
# code << "\n #{statement.to_verilog(block.mode.to_s)}"
|
305
|
+
# end
|
306
|
+
|
307
|
+
# FmI.fm_par.clear()
|
308
|
+
|
309
|
+
# code << "\n end\n\n"
|
310
|
+
# end
|
311
|
+
# return code
|
312
|
+
# end
|
311
313
|
|
312
314
|
|
313
315
|
# Process top layer of Block.
|
@@ -1814,6 +1816,15 @@ module HDLRuby::Low
|
|
1814
1816
|
end
|
1815
1817
|
end
|
1816
1818
|
|
1819
|
+
|
1820
|
+
# Generate verilog code for the TimeRepeat.
|
1821
|
+
class TimeRepeat
|
1822
|
+
def to_verilog(spc = 3)
|
1823
|
+
result = (" " * spc) + "repeat(#{self.number})" + "\n"
|
1824
|
+
result << self.statement.to_verilog(spc+3)
|
1825
|
+
end
|
1826
|
+
end
|
1827
|
+
|
1817
1828
|
# Those who disappeared.
|
1818
1829
|
#class SystemI
|
1819
1830
|
#class TypeTuple
|
@@ -2137,10 +2148,12 @@ module HDLRuby::Low
|
|
2137
2148
|
if behavior.block.is_a?(TimeBlock) then
|
2138
2149
|
# Tell it is a time behavior for further processing.
|
2139
2150
|
timebeh = true
|
2140
|
-
#
|
2141
|
-
|
2142
|
-
|
2143
|
-
|
2151
|
+
# Deprecated with new TimeRepeat.
|
2152
|
+
#
|
2153
|
+
# # Extract and translate the TimeRepeat separately.
|
2154
|
+
# behavior.each_block_deep do |blk|
|
2155
|
+
# codeC << blk.repeat_to_verilog!
|
2156
|
+
# end
|
2144
2157
|
# And generate an initial block.
|
2145
2158
|
codeC << " initial "
|
2146
2159
|
else
|
data/lib/HDLRuby/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: HDLRuby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.11.
|
4
|
+
version: 2.11.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lovic Gauthier
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-10-
|
11
|
+
date: 2022-10-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -148,6 +148,7 @@ files:
|
|
148
148
|
- lib/HDLRuby/hdr_samples/ram.rb
|
149
149
|
- lib/HDLRuby/hdr_samples/range_bench.rb
|
150
150
|
- lib/HDLRuby/hdr_samples/register_with_code_bench.rb
|
151
|
+
- lib/HDLRuby/hdr_samples/repeat_bench.rb
|
151
152
|
- lib/HDLRuby/hdr_samples/rom.rb
|
152
153
|
- lib/HDLRuby/hdr_samples/rom_nest.rb
|
153
154
|
- lib/HDLRuby/hdr_samples/ruby_fir_hw.rb
|