HDLRuby 2.3.5 → 2.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/lib/HDLRuby/hdr_samples/bstr_bench.rb +14 -0
- data/lib/HDLRuby/hdr_samples/with_fixpoint.rb +9 -0
- data/lib/HDLRuby/hdr_samples/with_linear.rb +3 -15
- data/lib/HDLRuby/hdr_samples/with_multi_channels.rb +300 -0
- data/lib/HDLRuby/hdrcc.rb +10 -1
- data/lib/HDLRuby/hruby_bstr.rb +5 -2
- data/lib/HDLRuby/hruby_high.rb +8 -0
- data/lib/HDLRuby/hruby_low.rb +107 -8
- data/lib/HDLRuby/hruby_low2c.rb +24 -7
- data/lib/HDLRuby/hruby_low_mutable.rb +90 -2
- data/lib/HDLRuby/hruby_low_resolve.rb +1 -0
- data/lib/HDLRuby/hruby_low_without_connection.rb +14 -0
- data/lib/HDLRuby/sim/hruby_sim.h +79 -37
- data/lib/HDLRuby/sim/hruby_sim_calc.c +69 -0
- data/lib/HDLRuby/sim/hruby_sim_core.c +32 -6
- data/lib/HDLRuby/sim/hruby_sim_vcd.c +380 -0
- data/lib/HDLRuby/sim/hruby_sim_vizualize.c +51 -12
- data/lib/HDLRuby/std/channel.rb +302 -60
- data/lib/HDLRuby/std/linear.rb +16 -8
- data/lib/HDLRuby/version.rb +1 -1
- metadata +5 -2
@@ -7,26 +7,51 @@
|
|
7
7
|
* generated by hruby_low2c.
|
8
8
|
**/
|
9
9
|
|
10
|
+
/* The print function pointers. */
|
11
|
+
|
12
|
+
PrinterS printer;
|
13
|
+
|
14
|
+
|
15
|
+
/** Initializes the visualization printer engine.
|
16
|
+
* @param print_time the time printer
|
17
|
+
* @param print_name the name printer
|
18
|
+
* @param print_value the value printer
|
19
|
+
* @param print_signal the signal state printer. */
|
20
|
+
void init_visualizer(void (*print_time)(unsigned long long),
|
21
|
+
void (*print_name)(Object),
|
22
|
+
void (*print_value)(Value),
|
23
|
+
void (*print_signal)(SignalI)) {
|
24
|
+
printer.print_time = print_time;
|
25
|
+
printer.print_name = print_name;
|
26
|
+
printer.print_value = print_value;
|
27
|
+
printer.print_signal = print_signal;
|
28
|
+
}
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
/* The default printing functions. */
|
34
|
+
|
10
35
|
/** Prints the time.
|
11
36
|
* @param time the time to show. */
|
12
|
-
void
|
37
|
+
static void default_print_time(unsigned long long time) {
|
13
38
|
printf("# %llups",time);
|
14
39
|
}
|
15
40
|
|
16
41
|
/** Prints the time and goes to the next line.
|
17
|
-
* @
|
18
|
-
void
|
19
|
-
|
42
|
+
* @par1am time the time to show. */
|
43
|
+
static void default_println_time(unsigned long long time) {
|
44
|
+
default_print_time(time);
|
20
45
|
printf("\n");
|
21
46
|
}
|
22
47
|
|
23
48
|
/** Prints the name of an object.
|
24
49
|
* @param object the object to print the name. */
|
25
|
-
void
|
50
|
+
static void default_print_name(Object object) {
|
26
51
|
/* Recurse on the owner if any. */
|
27
52
|
// printf("owner=%p\n",object->owner);
|
28
53
|
if (object->owner != NULL) {
|
29
|
-
|
54
|
+
default_print_name(object->owner);
|
30
55
|
printf("::");
|
31
56
|
}
|
32
57
|
/* Depending on the kind of object. */
|
@@ -48,7 +73,7 @@ void print_name(Object object) {
|
|
48
73
|
|
49
74
|
/** Prints a value.
|
50
75
|
* @param value the value to print */
|
51
|
-
void
|
76
|
+
static void default_print_value(Value value) {
|
52
77
|
if (value->numeric) {
|
53
78
|
unsigned long long width = type_width(value->type);
|
54
79
|
unsigned long long mask = 1ULL << (width-1);
|
@@ -77,15 +102,29 @@ void print_value(Value value) {
|
|
77
102
|
|
78
103
|
/** Prints a signal.
|
79
104
|
* @param signal the signal to show */
|
80
|
-
void
|
81
|
-
|
105
|
+
static void default_print_signal(SignalI signal) {
|
106
|
+
default_print_name((Object)signal);
|
82
107
|
printf(": ");
|
83
|
-
|
108
|
+
default_print_value(signal->f_value);
|
84
109
|
}
|
85
110
|
|
86
111
|
/** Prints a signal and goes to the next line.
|
87
112
|
* @param signal the signal to show */
|
88
|
-
void
|
89
|
-
|
113
|
+
static void default_println_signal(SignalI signal) {
|
114
|
+
default_print_signal(signal);
|
90
115
|
printf("\n");
|
91
116
|
}
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
/* Set up the visualizer. */
|
121
|
+
|
122
|
+
/** Set up the default vizualization engine.
|
123
|
+
* @param name the name of the vizualization. */
|
124
|
+
void init_default_visualizer(char* name) {
|
125
|
+
/* Initialize the vizualizer printer engine. */
|
126
|
+
init_visualizer(&default_println_time,
|
127
|
+
&default_print_name,
|
128
|
+
&default_print_value,
|
129
|
+
&default_println_signal);
|
130
|
+
}
|
data/lib/HDLRuby/std/channel.rb
CHANGED
@@ -325,6 +325,86 @@ module HDLRuby::High::Std
|
|
325
325
|
end
|
326
326
|
|
327
327
|
|
328
|
+
##
|
329
|
+
# Module giving the methods for accessing a channel instance.
|
330
|
+
module HchannelI
|
331
|
+
## Performs a read on the channel using +args+ and +ruby_block+
|
332
|
+
# as arguments.
|
333
|
+
# NOTE:
|
334
|
+
# * Will generate a port if not present.
|
335
|
+
# * Will generate an error if a read is tempted while the read
|
336
|
+
# port has been declared within another system.
|
337
|
+
def read(*args,&ruby_block)
|
338
|
+
# Is there a port to read?
|
339
|
+
unless self.read_port then
|
340
|
+
# No, generate a new one.
|
341
|
+
# Is it possible to be inout?
|
342
|
+
if self.inout? then
|
343
|
+
# Yes, create an inout port.
|
344
|
+
self.inout(HDLRuby.uniq_name)
|
345
|
+
else
|
346
|
+
# No, create an input port.
|
347
|
+
self.input(HDLRuby.uniq_name)
|
348
|
+
end
|
349
|
+
end
|
350
|
+
# Ensure the read port is within current system.
|
351
|
+
unless self.read_port.scope.system != HDLRuby::High.cur_system then
|
352
|
+
raise "Cannot read from a port external of current system for channel " + self.name
|
353
|
+
end
|
354
|
+
# Performs the read.
|
355
|
+
self.read_port.read(*args,&ruby_block)
|
356
|
+
end
|
357
|
+
|
358
|
+
## Performs a write on the channel using +args+ and +ruby_block+
|
359
|
+
# as arguments.
|
360
|
+
# NOTE:
|
361
|
+
# * Will generate a port if not present.
|
362
|
+
# * Will generate an error if a read is tempted while the read
|
363
|
+
# port has been declared within another system.
|
364
|
+
def write(*args,&ruby_block)
|
365
|
+
# Is there a port to write?
|
366
|
+
unless self.write_port then
|
367
|
+
# No, generate a new one.
|
368
|
+
# Is it possible to be inout?
|
369
|
+
if self.inout? then
|
370
|
+
# Yes, create an inout port.
|
371
|
+
self.inout(HDLRuby.uniq_name)
|
372
|
+
else
|
373
|
+
# No, create an output port.
|
374
|
+
self.output(HDLRuby.uniq_name)
|
375
|
+
end
|
376
|
+
end
|
377
|
+
# Ensure the write port is within current system.
|
378
|
+
unless self.write_port.scope.system != HDLRuby::High.cur_system then
|
379
|
+
raise "Cannot write from a port external of current system for channel " + self.name
|
380
|
+
end
|
381
|
+
# Performs the write.
|
382
|
+
self.write_port.write(*args,&ruby_block)
|
383
|
+
end
|
384
|
+
|
385
|
+
|
386
|
+
## Performs a reset on the channel using +args+ and +ruby_block+
|
387
|
+
# as arguments.
|
388
|
+
def reset(*args,&ruby_block)
|
389
|
+
# Gain access to the writer as local variable.
|
390
|
+
reseter_proc = @inout_reseter_proc
|
391
|
+
# # The context is the one of the writer.
|
392
|
+
# Execute the code generating the writer in context.
|
393
|
+
HDLRuby::High.space_push(@namespace)
|
394
|
+
HDLRuby::High.cur_block.open do
|
395
|
+
instance_exec(ruby_block,*args,&reseter_proc)
|
396
|
+
end
|
397
|
+
HDLRuby::High.space_pop
|
398
|
+
end
|
399
|
+
|
400
|
+
|
401
|
+
# Wrap with +args+ arguments.
|
402
|
+
def wrap(*args)
|
403
|
+
return ChannelB.new(self,*args)
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
|
328
408
|
|
329
409
|
##
|
330
410
|
# Describes a high-level channel instance.
|
@@ -864,12 +944,12 @@ module HDLRuby::High::Std
|
|
864
944
|
# Ensure the port is not already existing.
|
865
945
|
if @read_port then
|
866
946
|
raise "Read port already declared for channel instance: " +
|
867
|
-
self.name
|
947
|
+
self.name.to_s
|
868
948
|
end
|
869
949
|
|
870
950
|
if @write_port then
|
871
951
|
raise "Write port already declared for channel instance: " +
|
872
|
-
self.name
|
952
|
+
self.name.to_s
|
873
953
|
end
|
874
954
|
|
875
955
|
# Access the ports
|
@@ -1006,76 +1086,238 @@ module HDLRuby::High::Std
|
|
1006
1086
|
# return chp
|
1007
1087
|
# end
|
1008
1088
|
|
1089
|
+
# Standard channel access is given is HchannelI module.
|
1090
|
+
include HchannelI
|
1009
1091
|
|
1010
1092
|
|
1011
|
-
## Performs a read on the channel using +args+ and +ruby_block+
|
1012
|
-
# as arguments.
|
1013
|
-
# NOTE:
|
1014
|
-
# * Will generate a port if not present.
|
1015
|
-
# * Will generate an error if a read is tempted while the read
|
1016
|
-
# port has been declared within another system.
|
1017
|
-
def read(*args,&ruby_block)
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1093
|
+
# ## Performs a read on the channel using +args+ and +ruby_block+
|
1094
|
+
# # as arguments.
|
1095
|
+
# # NOTE:
|
1096
|
+
# # * Will generate a port if not present.
|
1097
|
+
# # * Will generate an error if a read is tempted while the read
|
1098
|
+
# # port has been declared within another system.
|
1099
|
+
# def read(*args,&ruby_block)
|
1100
|
+
# # Is there a port to read?
|
1101
|
+
# unless self.read_port then
|
1102
|
+
# # No, generate a new one.
|
1103
|
+
# # Is it possible to be inout?
|
1104
|
+
# if self.inout? then
|
1105
|
+
# # Yes, create an inout port.
|
1106
|
+
# self.inout(HDLRuby.uniq_name)
|
1107
|
+
# else
|
1108
|
+
# # No, create an input port.
|
1109
|
+
# self.input(HDLRuby.uniq_name)
|
1110
|
+
# end
|
1111
|
+
# end
|
1112
|
+
# # Ensure the read port is within current system.
|
1113
|
+
# unless self.read_port.scope.system != HDLRuby::High.cur_system then
|
1114
|
+
# raise "Cannot read from a port external of current system for channel " + self.name
|
1115
|
+
# end
|
1116
|
+
# # Performs the read.
|
1117
|
+
# self.read_port.read(*args,&ruby_block)
|
1118
|
+
# end
|
1119
|
+
#
|
1120
|
+
# ## Performs a write on the channel using +args+ and +ruby_block+
|
1121
|
+
# # as arguments.
|
1122
|
+
# # NOTE:
|
1123
|
+
# # * Will generate a port if not present.
|
1124
|
+
# # * Will generate an error if a read is tempted while the read
|
1125
|
+
# # port has been declared within another system.
|
1126
|
+
# def write(*args,&ruby_block)
|
1127
|
+
# # Is there a port to write?
|
1128
|
+
# unless self.write_port then
|
1129
|
+
# # No, generate a new one.
|
1130
|
+
# # Is it possible to be inout?
|
1131
|
+
# if self.inout? then
|
1132
|
+
# # Yes, create an inout port.
|
1133
|
+
# self.inout(HDLRuby.uniq_name)
|
1134
|
+
# else
|
1135
|
+
# # No, create an output port.
|
1136
|
+
# self.output(HDLRuby.uniq_name)
|
1137
|
+
# end
|
1138
|
+
# end
|
1139
|
+
# # Ensure the write port is within current system.
|
1140
|
+
# unless self.write_port.scope.system != HDLRuby::High.cur_system then
|
1141
|
+
# raise "Cannot write from a port external of current system for channel " + self.name
|
1142
|
+
# end
|
1143
|
+
# # Performs the write.
|
1144
|
+
# self.write_port.write(*args,&ruby_block)
|
1145
|
+
# end
|
1146
|
+
#
|
1147
|
+
|
1148
|
+
# ## Performs a reset on the channel using +args+ and +ruby_block+
|
1149
|
+
# # as arguments.
|
1150
|
+
# def reset(*args,&ruby_block)
|
1151
|
+
# # Gain access to the writer as local variable.
|
1152
|
+
# reseter_proc = @inout_reseter_proc
|
1153
|
+
# # # The context is the one of the writer.
|
1154
|
+
# # Execute the code generating the writer in context.
|
1155
|
+
# HDLRuby::High.space_push(@namespace)
|
1156
|
+
# HDLRuby::High.cur_block.open do
|
1157
|
+
# instance_exec(ruby_block,*args,&reseter_proc)
|
1158
|
+
# end
|
1159
|
+
# HDLRuby::High.space_pop
|
1160
|
+
# end
|
1161
|
+
end
|
1162
|
+
|
1163
|
+
# Describes channel instance wrapper (Box) for fixing arugments.
|
1164
|
+
class ChannelB
|
1165
|
+
include HDLRuby::High::Hmissing
|
1166
|
+
include HchannelI
|
1167
|
+
|
1168
|
+
# Create a new channel box over +channelI+ channel instance using
|
1169
|
+
# +args+ for fixing the arguments as follows:
|
1170
|
+
# It can also be three lists for seperate read, write and access
|
1171
|
+
# procedures using named arguments as:
|
1172
|
+
# read: <read arguments>, write: <write arguments>,
|
1173
|
+
# access: <access arguments>
|
1174
|
+
def initialize(channelI,*args)
|
1175
|
+
# Ensure port is a channel port.
|
1176
|
+
unless channelI.is_a?(ChannelI) || channel.is_a?(ChannelB)
|
1177
|
+
raise "Invalid class for a channel instance: #{ch.class}"
|
1029
1178
|
end
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1179
|
+
@channelI = channelI
|
1180
|
+
# Process the arguments.
|
1181
|
+
if args.size == 1 && args[0].is_a?(Hash) then
|
1182
|
+
# Read, write and access are separated.
|
1183
|
+
@args_read = args[0][:read]
|
1184
|
+
@args_write = args[0][:write]
|
1185
|
+
@args_access = args[0][:access]
|
1186
|
+
else
|
1187
|
+
@args_read = args
|
1188
|
+
@args_write = args.clone
|
1189
|
+
@args_access = args.clone
|
1033
1190
|
end
|
1034
|
-
# Performs the read.
|
1035
|
-
self.read_port.read(*args,&ruby_block)
|
1036
1191
|
end
|
1192
|
+
|
1193
|
+
# Delegates to the boxed channel instance.
|
1194
|
+
|
1195
|
+
# The name of the channel instance.
|
1196
|
+
def name
|
1197
|
+
return @channelI.name
|
1198
|
+
end
|
1199
|
+
|
1200
|
+
# The scope the channel has been created in.
|
1201
|
+
def scope
|
1202
|
+
return @channelI.scope
|
1203
|
+
end
|
1204
|
+
|
1205
|
+
# The namespace associated with the current execution when
|
1206
|
+
# building a channel.
|
1207
|
+
def namespace
|
1208
|
+
return @channelI.namespace
|
1209
|
+
end
|
1210
|
+
|
1211
|
+
# The read port if any.
|
1212
|
+
def read_port
|
1213
|
+
return @read_port
|
1214
|
+
end
|
1215
|
+
|
1216
|
+
# The write port if any.
|
1217
|
+
def write_port
|
1218
|
+
return @write_port
|
1219
|
+
end
|
1220
|
+
|
1221
|
+
# Methods used on the channel outside its definition.
|
1037
1222
|
|
1038
|
-
|
1039
|
-
#
|
1040
|
-
#
|
1041
|
-
# *
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1223
|
+
# Gets branch channel +name+.
|
1224
|
+
# NOTE:
|
1225
|
+
# * +name+ can be of any type on purpose.
|
1226
|
+
# * The wrapping arguments are not transmitted to the branch.
|
1227
|
+
def branch(name,*args)
|
1228
|
+
return @channelI.branch(name,*args)
|
1229
|
+
end
|
1230
|
+
|
1231
|
+
## Tells if the channel support inout port.
|
1232
|
+
def inout?
|
1233
|
+
return @channelI.inout?
|
1234
|
+
end
|
1235
|
+
|
1236
|
+
|
1237
|
+
# Reader, writer and accesser side.
|
1238
|
+
|
1239
|
+
## Declares the reader port as and assigned them to +name+.
|
1240
|
+
def input(name = nil)
|
1241
|
+
# Ensure name is a symbol.
|
1242
|
+
name = HDLRuby.uniq_name unless name
|
1243
|
+
name = name.to_sym
|
1244
|
+
# Ensure the port is not already existing.
|
1245
|
+
if @read_port then
|
1246
|
+
raise "Read port already declared for channel instance: " +
|
1247
|
+
self.name
|
1056
1248
|
end
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1249
|
+
|
1250
|
+
# Create a read port for the encaspulted channel.
|
1251
|
+
real_port = @channelI.read_port
|
1252
|
+
real_port = @channelI.input unless real_port
|
1253
|
+
|
1254
|
+
# Wrap it to a new port using.
|
1255
|
+
chp = real_port.wrap(read: @args_read)
|
1256
|
+
|
1257
|
+
HDLRuby::High.space_reg(name) { chp }
|
1258
|
+
# Save the port in the channe to avoid conflicting declaration.
|
1259
|
+
@read_port = chp
|
1260
|
+
return chp
|
1261
|
+
end
|
1262
|
+
|
1263
|
+
## Declares the ports for the writer and assigned them to +name+.
|
1264
|
+
def output(name = nil)
|
1265
|
+
# Ensure name is a symbol.
|
1266
|
+
name = HDLRuby.uniq_name unless name
|
1267
|
+
name = name.to_sym
|
1268
|
+
# Ensure the port is not already existing.
|
1269
|
+
if @write_port then
|
1270
|
+
raise "Read port already declared for channel instance: " +
|
1271
|
+
self.name
|
1060
1272
|
end
|
1061
|
-
|
1062
|
-
|
1273
|
+
|
1274
|
+
# Create a write port for the encaspulted channel.
|
1275
|
+
real_port = @channelI.write_port
|
1276
|
+
real_port = @channelI.output unless real_port
|
1277
|
+
|
1278
|
+
# Wrap it to a new port using.
|
1279
|
+
chp = real_port.wrap(write: @args_write)
|
1280
|
+
|
1281
|
+
HDLRuby::High.space_reg(name) { chp }
|
1282
|
+
# Save the port in the channe to avoid conflicting declaration.
|
1283
|
+
@write_port = chp
|
1284
|
+
return chp
|
1063
1285
|
end
|
1064
|
-
|
1065
1286
|
|
1066
|
-
|
1067
|
-
|
1068
|
-
def
|
1069
|
-
#
|
1070
|
-
|
1071
|
-
|
1072
|
-
#
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1287
|
+
|
1288
|
+
## Declares the accesser port and assigned them to +name+.
|
1289
|
+
def inout(name = nil)
|
1290
|
+
# Ensure name is a symbol.
|
1291
|
+
name = HDLRuby.uniq_name unless name
|
1292
|
+
name = name.to_sym
|
1293
|
+
# Ensure the port is not already existing.
|
1294
|
+
if @read_port then
|
1295
|
+
raise "Read port already declared for channel instance: " +
|
1296
|
+
self.name
|
1076
1297
|
end
|
1077
|
-
|
1298
|
+
if @write_port then
|
1299
|
+
raise "Write port already declared for channel instance: " +
|
1300
|
+
self.name
|
1301
|
+
end
|
1302
|
+
|
1303
|
+
# Create a write port for the encaspulted channel.
|
1304
|
+
if @channelI.read_port == @channelI.write_port then
|
1305
|
+
real_port = @channelI.read_port
|
1306
|
+
real_port = @channelI.inout unless real_port
|
1307
|
+
else
|
1308
|
+
raise "Inout port not supported for channel #{@channelI}"
|
1309
|
+
end
|
1310
|
+
|
1311
|
+
# Wrap it to a new port using.
|
1312
|
+
chp = real_port.wrap(read: @args_read, write: @args_write)
|
1313
|
+
|
1314
|
+
HDLRuby::High.space_reg(name) { chp }
|
1315
|
+
# Save the port in the channe to avoid conflicting declaration.
|
1316
|
+
@write_port = chp
|
1317
|
+
@read_port = chp
|
1318
|
+
return chp
|
1078
1319
|
end
|
1320
|
+
|
1079
1321
|
end
|
1080
1322
|
|
1081
1323
|
|