HDLRuby 2.3.6 → 2.4.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- # Is there a port to read?
1019
- unless self.read_port then
1020
- # No, generate a new one.
1021
- # Is it possible to be inout?
1022
- if self.inout? then
1023
- # Yes, create an inout port.
1024
- self.inout(HDLRuby.uniq_name)
1025
- else
1026
- # No, create an input port.
1027
- self.input(HDLRuby.uniq_name)
1028
- end
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
- # Ensure the read port is within current system.
1031
- unless self.read_port.scope.system != HDLRuby::High.cur_system then
1032
- raise "Cannot read from a port external of current system for channel " + self.name
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
- ## Performs a write on the channel using +args+ and +ruby_block+
1039
- # as arguments.
1040
- # NOTE:
1041
- # * Will generate a port if not present.
1042
- # * Will generate an error if a read is tempted while the read
1043
- # port has been declared within another system.
1044
- def write(*args,&ruby_block)
1045
- # Is there a port to write?
1046
- unless self.write_port then
1047
- # No, generate a new one.
1048
- # Is it possible to be inout?
1049
- if self.inout? then
1050
- # Yes, create an inout port.
1051
- self.inout(HDLRuby.uniq_name)
1052
- else
1053
- # No, create an output port.
1054
- self.output(HDLRuby.uniq_name)
1055
- end
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
- # Ensure the write port is within current system.
1058
- unless self.write_port.scope.system != HDLRuby::High.cur_system then
1059
- raise "Cannot write from a port external of current system for channel " + self.name
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
- # Performs the write.
1062
- self.write_port.write(*args,&ruby_block)
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
- ## Performs a reset on the channel using +args+ and +ruby_block+
1067
- # as arguments.
1068
- def reset(*args,&ruby_block)
1069
- # Gain access to the writer as local variable.
1070
- reseter_proc = @inout_reseter_proc
1071
- # # The context is the one of the writer.
1072
- # Execute the code generating the writer in context.
1073
- HDLRuby::High.space_push(@namespace)
1074
- HDLRuby::High.cur_block.open do
1075
- instance_exec(ruby_block,*args,&reseter_proc)
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
- HDLRuby::High.space_pop
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
 
@@ -52,10 +52,18 @@ module HDLRuby::High::Std
52
52
  end
53
53
  # Redefine the multiplication and division for fixed point.
54
54
  typ.define_operator(:*) do |left,right|
55
- (left.as([isize+fsize*2])*right) >> fsize
55
+ if (typ.signed?) then
56
+ (left.as(signed[isize+fsize*2])*right) >> fsize
57
+ else
58
+ (left.as([isize+fsize*2])*right) >> fsize
59
+ end
56
60
  end
57
61
  typ.define_operator(:/) do |left,right|
58
- (left.as([isize+fsize*2]) << fsize) / right
62
+ if (typ.signed?) then
63
+ (left.as(signed[isize+fsize*2]) << fsize) / right
64
+ else
65
+ (left.as([isize+fsize*2]) << fsize) / right
66
+ end
59
67
  end
60
68
  typ
61
69
  end
@@ -209,37 +209,57 @@ module HDLRuby::High::Std
209
209
  # lv and rv are valid.
210
210
  lvoks = lefts.each_with_index.map { |left,i| inner :"lvok#{i}" }
211
211
  inner :rvok
212
+ woks = lefts.each_with_index.map { |left,i| inner :"wok#{i}" }
212
213
  # Run flag
213
214
  inner :run
214
215
  par(ev) do
215
216
  ack <= 0
216
217
  run <= 0
218
+ hif(~run) do
219
+ rvok <= 0
220
+ lefts.each_with_index do |left,i|
221
+ lvoks[i] <= 0
222
+ # avs[i] <= 0
223
+ woks[i] <= 0
224
+ end
225
+ end
217
226
  hif(req | run) do
218
227
  run <= 1
219
228
  # Computation request.
220
- right.read(rv) { rvok <= 1 }
229
+ hif(~rvok) { right.read(rv) { rvok <= 1 } }
221
230
  lefts.each_with_index do |left,i|
222
- left.read(lvs[i]) { lvoks[i] <= 1 }
231
+ hif(~lvoks[i]) { left.read(lvs[i]) { lvoks[i] <= 1 } }
223
232
  # accs[i].read(avs[i])
224
- hif(lvoks[i] & rvok) do
233
+ hif(lvoks[i] & rvok & ~woks[i]) do
225
234
  ack <= 1
226
235
  run <= 0
227
- # accs[i].write(add.(avs[i],mul.(lvs[i],rv)))
228
236
  seq do
229
237
  avs[i] <= add.(avs[i],mul.(lvs[i],rv))
230
- accs[i].write(avs[i])
238
+ accs[i].write(avs[i]) do
239
+ woks[i] <= 1
240
+ # seq do
241
+ # lvoks[i] <= 0
242
+ # rvok <= lvoks.reduce(:|)
243
+ # end
244
+ end
231
245
  end
232
246
  end
247
+ hif (woks.reduce(:&)) do
248
+ woks.each { |wok| wok <= 0 }
249
+ lvoks.each { | lvok| lvok <=0 }
250
+ rvok <= 0
251
+ end
233
252
  end
234
253
  end
235
- helse do
236
- rvok <= 0
237
- lefts.each_with_index do |left,i|
238
- lvoks[i] <= 0
239
- # accs[i].write(0)
240
- avs[i] <= 0
241
- end
242
- end
254
+ helse { avs.each {|av| av <= 0 } }
255
+ # helse do
256
+ # rvok <= 0
257
+ # lefts.each_with_index do |left,i|
258
+ # lvoks[i] <= 0
259
+ # # accs[i].write(0)
260
+ # avs[i] <= 0
261
+ # end
262
+ # end
243
263
  end
244
264
  end
245
265