HDLRuby 2.11.3 → 2.11.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|