HDLRuby 2.11.2 → 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 +325 -73
- data/ext/hruby_sim/hruby_sim.h +11 -1
- data/ext/hruby_sim/hruby_sim_calc.c +11 -8
- data/ext/hruby_sim/hruby_sim_core.c +8 -6
- data/ext/hruby_sim/hruby_sim_tree_calc.c +14 -0
- data/ext/hruby_sim/hruby_value_pool.c +6 -4
- 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 +119 -74
- 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
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. */
|
@@ -5,9 +5,9 @@
|
|
5
5
|
#include <limits.h>
|
6
6
|
#include "hruby_sim.h"
|
7
7
|
|
8
|
-
#ifndef alloca
|
9
|
-
#define alloca(x) __builtin_alloca(x)
|
10
|
-
#endif
|
8
|
+
// #ifndef alloca
|
9
|
+
// #define alloca(x) __builtin_alloca(x)
|
10
|
+
// #endif
|
11
11
|
|
12
12
|
|
13
13
|
/**
|
@@ -147,7 +147,7 @@ Type get_type_signed() {
|
|
147
147
|
* @number the number of elements */
|
148
148
|
Type make_type_vector(Type base, unsigned long long number) {
|
149
149
|
/* Create the type. */
|
150
|
-
Type type = calloc(sizeof(TypeS)
|
150
|
+
Type type = calloc(1,sizeof(TypeS));
|
151
151
|
type->base = type_width(base);
|
152
152
|
type->number = number;
|
153
153
|
type->flags = base->flags;
|
@@ -201,7 +201,7 @@ Value make_value(Type type, int numeric) {
|
|
201
201
|
/* Compute the size in words of the data contained in the value. */
|
202
202
|
unsigned long long width = type_width(type);
|
203
203
|
/* Allocate the value. */
|
204
|
-
Value res = calloc(sizeof(ValueS)
|
204
|
+
Value res = calloc(1,sizeof(ValueS));
|
205
205
|
/* Allocates the data of the value. */
|
206
206
|
if (!numeric) {
|
207
207
|
/* Allocate the bit string and fill it with u (undefined) by default. */
|
@@ -232,7 +232,7 @@ void resize_value(Value value, unsigned long long size) {
|
|
232
232
|
/* Free the former data. */
|
233
233
|
free(value->data_str);
|
234
234
|
/* Reallocate it. */
|
235
|
-
value->data_str = calloc(sizeof(char)
|
235
|
+
value->data_str = calloc(size*2,sizeof(char));
|
236
236
|
/* Update the size. */
|
237
237
|
value->capacity = size*2;
|
238
238
|
}
|
@@ -2977,12 +2977,15 @@ Value concat_valueP(unsigned int num, int dir, Value dst, Value* values) {
|
|
2977
2977
|
}
|
2978
2978
|
Value concat_valueV(unsigned int num, int dir, Value dst, va_list args) {
|
2979
2979
|
unsigned int i;
|
2980
|
-
Value* values = alloca(num*sizeof(Value)); /* The values to concatenate. */
|
2980
|
+
// Value* values = alloca(num*sizeof(Value)); /* The values to concatenate. */
|
2981
|
+
Value* values = calloc(num,sizeof(Value)); /* The values to concatenate. */
|
2981
2982
|
/* Copy the arguments to values for easier processing. */
|
2982
2983
|
for(i=0; i<num; ++i) {
|
2983
2984
|
values[i] = va_arg(args,Value);
|
2984
2985
|
}
|
2985
|
-
|
2986
|
+
Value res = concat_valueP(num,dir,dst,values);
|
2987
|
+
free(values);
|
2988
|
+
return res;
|
2986
2989
|
}
|
2987
2990
|
Value concat_value(unsigned int num, int dir, Value dst, ...) {
|
2988
2991
|
va_list args;
|
@@ -72,11 +72,12 @@ void register_timed_behavior(Behavior behavior) {
|
|
72
72
|
if (cap_timed_behaviors == 0) {
|
73
73
|
/* Need to create the array containing the timed behaviors. */
|
74
74
|
cap_timed_behaviors = 5;
|
75
|
-
timed_behaviors = calloc(sizeof(Behavior)
|
75
|
+
timed_behaviors = calloc(cap_timed_behaviors,sizeof(Behavior));
|
76
76
|
} else {
|
77
77
|
/* Need to increase the capacity. */
|
78
|
-
Behavior* behaviors = calloc(sizeof(Behavior)
|
79
|
-
memcpy(behaviors,timed_behaviors,sizeof(Behavior)*cap_timed_behaviors);
|
78
|
+
Behavior* behaviors = calloc(cap_timed_behaviors*2,sizeof(Behavior));
|
79
|
+
// memcpy(behaviors,timed_behaviors,sizeof(Behavior)*cap_timed_behaviors);
|
80
|
+
memcpy(behaviors,timed_behaviors,sizeof(Behavior[cap_timed_behaviors]));
|
80
81
|
timed_behaviors = behaviors;
|
81
82
|
cap_timed_behaviors *= 2;
|
82
83
|
}
|
@@ -93,11 +94,12 @@ void register_signal(SignalI signal) {
|
|
93
94
|
if (cap_all_signals == 0) {
|
94
95
|
/* Need to create the array containing the timed behaviors. */
|
95
96
|
cap_all_signals = 100;
|
96
|
-
all_signals = calloc(sizeof(SignalI)
|
97
|
+
all_signals = calloc(cap_all_signals,sizeof(SignalI));
|
97
98
|
} else {
|
98
99
|
/* Need to increase the capacity. */
|
99
|
-
SignalI* new_signals = calloc(sizeof(SignalI)
|
100
|
-
memcpy(new_signals,all_signals,sizeof(SignalI)*cap_all_signals);
|
100
|
+
SignalI* new_signals = calloc(cap_all_signals*2,sizeof(SignalI));
|
101
|
+
// memcpy(new_signals,all_signals,sizeof(SignalI)*cap_all_signals);
|
102
|
+
memcpy(new_signals,all_signals,sizeof(SignalI[cap_all_signals]));
|
101
103
|
cap_all_signals *= 2;
|
102
104
|
all_signals=new_signals;
|
103
105
|
}
|
@@ -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;
|
@@ -20,9 +20,10 @@ Value get_value() {
|
|
20
20
|
if (pool_cap == 0) {
|
21
21
|
/* First allocation. */
|
22
22
|
pool_cap = 16;
|
23
|
-
pool_values = (Value*)malloc(pool_cap*sizeof(Value));
|
23
|
+
// pool_values = (Value*)malloc(pool_cap*sizeof(Value));
|
24
|
+
pool_values = (Value*)calloc(pool_cap,sizeof(Value));
|
24
25
|
/* Allocate the new values. */
|
25
|
-
ValueS* new_values = (ValueS*)calloc(sizeof(ValueS)
|
26
|
+
ValueS* new_values = (ValueS*)calloc(pool_cap,sizeof(ValueS));
|
26
27
|
/* Assign them to the pool. */
|
27
28
|
unsigned int i;
|
28
29
|
for(i=0; i<pool_cap; ++i) {
|
@@ -32,7 +33,8 @@ Value get_value() {
|
|
32
33
|
else if (pool_pos == pool_cap) {
|
33
34
|
/* Need to increase the pool capacity. */
|
34
35
|
pool_cap = pool_cap * 2;
|
35
|
-
pool_values = (Value*)realloc(pool_values,pool_cap*sizeof(Value));
|
36
|
+
// pool_values = (Value*)realloc(pool_values,pool_cap*sizeof(Value));
|
37
|
+
pool_values = (Value*)realloc(pool_values,sizeof(Value[pool_cap]));
|
36
38
|
if (pool_values == NULL) {
|
37
39
|
perror("Internal error with the pool of values.");
|
38
40
|
exit(1);
|
@@ -40,7 +42,7 @@ Value get_value() {
|
|
40
42
|
/* Allocate the new values. */
|
41
43
|
/* Note: now pool_pos is the old pool_cap and is also the number
|
42
44
|
* of new values to allocate. */
|
43
|
-
ValueS* new_values = (ValueS*)calloc(sizeof(ValueS)
|
45
|
+
ValueS* new_values = (ValueS*)calloc(pool_pos,sizeof(ValueS));
|
44
46
|
/* Assign them to the pool. */
|
45
47
|
unsigned int i;
|
46
48
|
for(i=0; i<pool_pos; ++i) {
|
@@ -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
|