origen_stil 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/config/commands.rb +35 -38
- data/config/version.rb +2 -3
- data/grammars/stil.rb +63 -105
- data/lib/origen_stil.rb +11 -5
- data/lib/origen_stil/pattern.rb +135 -52
- data/lib/origen_stil/processor/base.rb +1 -0
- data/lib/origen_stil/processor/expression.rb +70 -0
- data/lib/origen_stil/processor/pattern.rb +4 -1
- data/lib/origen_stil/processor/pin_groups.rb +35 -3
- data/lib/origen_stil/processor/pins.rb +7 -0
- data/lib/origen_stil/processor/timesets.rb +8 -2
- data/pattern/example3.rb +7 -0
- metadata +5 -4
- data/bin/fix_my_workspace +0 -100
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 259036f2835904086a3ee116686b8deea693701480214760345f255b7f5a8b11
|
4
|
+
data.tar.gz: d7eb35222e5ac396c59f03274464321c71f82487ba0f334d8d65db471cbda997
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c04ff6b66af25e716fbd228266d1ccad13ebd921ab01490fedb4126db563b4787c39d973f6b547898ae6f8ce709c7131482b2fa4ad0d4dde1c73900d96b0cb1f
|
7
|
+
data.tar.gz: 30e9d17e1cae9969b10b63edb997587ae31fa41a8f3c3fd1e6229f0079a9a61da38061f79748516dbea2587b6a3964417b2fe41460d72a41374db6883bdb6ed2
|
data/config/commands.rb
CHANGED
@@ -33,42 +33,39 @@ when "tags"
|
|
33
33
|
# control flowing back to Origen
|
34
34
|
exit 0
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
# Example of how to make a command to run unit tests, this simply invokes RSpec on
|
37
|
+
# the spec directory
|
38
|
+
when "specs"
|
39
|
+
require "rspec"
|
40
|
+
exit RSpec::Core::Runner.run(['spec'])
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
#
|
69
|
-
# status = status == 1 ? 1 : result
|
70
|
-
# end
|
71
|
-
# exit status # Exit with a 1 on the event of a failure per std unix result codes
|
42
|
+
# Example of how to make a command to run diff-based tests
|
43
|
+
when "examples", "test"
|
44
|
+
Origen.load_application
|
45
|
+
status = 0
|
46
|
+
|
47
|
+
# Pattern generator tests
|
48
|
+
ARGV = %w(example3 -r approved -e v93k)
|
49
|
+
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
50
|
+
|
51
|
+
if Origen.app.stats.changed_files == 0 &&
|
52
|
+
Origen.app.stats.new_files == 0 &&
|
53
|
+
Origen.app.stats.changed_patterns == 0 &&
|
54
|
+
Origen.app.stats.new_patterns == 0
|
55
|
+
|
56
|
+
Origen.app.stats.report_pass
|
57
|
+
else
|
58
|
+
Origen.app.stats.report_fail
|
59
|
+
status = 1
|
60
|
+
end
|
61
|
+
puts
|
62
|
+
if @command == "test"
|
63
|
+
Origen.app.unload_target!
|
64
|
+
require "rspec"
|
65
|
+
result = RSpec::Core::Runner.run(['spec'])
|
66
|
+
status = status == 1 ? 1 : result
|
67
|
+
end
|
68
|
+
exit status # Exit with a 1 on the event of a failure per std unix result codes
|
72
69
|
|
73
70
|
# Always leave an else clause to allow control to fall back through to the
|
74
71
|
# Origen command handler.
|
@@ -79,8 +76,8 @@ else
|
|
79
76
|
@application_commands = <<-EOT
|
80
77
|
tags Build a tags file for this app
|
81
78
|
build Build/compile the latest grammar file(s)
|
79
|
+
specs Run the specs (tests), -c will enable coverage
|
80
|
+
examples Run the examples (tests), -c will enable coverage
|
81
|
+
test Run both specs and examples, -c will enable coverage
|
82
82
|
EOT
|
83
|
-
# specs Run the specs (tests), -c will enable coverage
|
84
|
-
# examples Run the examples (tests), -c will enable coverage
|
85
|
-
# test Run both specs and examples, -c will enable coverage
|
86
83
|
end
|
data/config/version.rb
CHANGED
data/grammars/stil.rb
CHANGED
@@ -254,7 +254,7 @@ module OrigenSTIL
|
|
254
254
|
elements[1]
|
255
255
|
end
|
256
256
|
|
257
|
-
def
|
257
|
+
def expression_subset
|
258
258
|
elements[2]
|
259
259
|
end
|
260
260
|
|
@@ -311,7 +311,7 @@ module OrigenSTIL
|
|
311
311
|
r5 = _nt_s
|
312
312
|
s3 << r5
|
313
313
|
if r5
|
314
|
-
r6 =
|
314
|
+
r6 = _nt_expression_subset
|
315
315
|
s3 << r6
|
316
316
|
if r6
|
317
317
|
r7 = _nt_s
|
@@ -352,153 +352,104 @@ module OrigenSTIL
|
|
352
352
|
r0
|
353
353
|
end
|
354
354
|
|
355
|
-
def
|
355
|
+
def _nt_expression_subset
|
356
356
|
start_index = index
|
357
|
-
if node_cache[:
|
358
|
-
cached = node_cache[:
|
357
|
+
if node_cache[:expression_subset].has_key?(index)
|
358
|
+
cached = node_cache[:expression_subset][index]
|
359
359
|
if cached
|
360
|
-
node_cache[:
|
360
|
+
node_cache[:expression_subset][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
361
361
|
@index = cached.interval.end
|
362
362
|
end
|
363
363
|
return cached
|
364
364
|
end
|
365
365
|
|
366
366
|
i0 = index
|
367
|
-
r1 =
|
367
|
+
r1 = _nt_add
|
368
368
|
if r1
|
369
369
|
r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
|
370
370
|
r0 = r1
|
371
371
|
else
|
372
|
-
r2 =
|
372
|
+
r2 = _nt_subtract
|
373
373
|
if r2
|
374
374
|
r2 = SyntaxNode.new(input, (index-1)...index) if r2 == true
|
375
375
|
r0 = r2
|
376
376
|
else
|
377
|
-
|
378
|
-
r0 = nil
|
379
|
-
end
|
380
|
-
end
|
381
|
-
|
382
|
-
node_cache[:expression][start_index] = r0
|
383
|
-
|
384
|
-
r0
|
385
|
-
end
|
386
|
-
|
387
|
-
def _nt_sigref_expression
|
388
|
-
start_index = index
|
389
|
-
if node_cache[:sigref_expression].has_key?(index)
|
390
|
-
cached = node_cache[:sigref_expression][index]
|
391
|
-
if cached
|
392
|
-
node_cache[:sigref_expression][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
393
|
-
@index = cached.interval.end
|
394
|
-
end
|
395
|
-
return cached
|
396
|
-
end
|
397
|
-
|
398
|
-
s0, i0 = [], index
|
399
|
-
loop do
|
400
|
-
i1 = index
|
401
|
-
r2 = _nt_add
|
402
|
-
if r2
|
403
|
-
r2 = SyntaxNode.new(input, (index-1)...index) if r2 == true
|
404
|
-
r1 = r2
|
405
|
-
else
|
406
|
-
r3 = _nt_subtract
|
377
|
+
r3 = _nt_name
|
407
378
|
if r3
|
408
379
|
r3 = SyntaxNode.new(input, (index-1)...index) if r3 == true
|
409
|
-
|
380
|
+
r0 = r3
|
410
381
|
else
|
411
|
-
r4 =
|
382
|
+
r4 = _nt_paren_expression
|
412
383
|
if r4
|
413
384
|
r4 = SyntaxNode.new(input, (index-1)...index) if r4 == true
|
414
|
-
|
385
|
+
r0 = r4
|
415
386
|
else
|
416
|
-
|
417
|
-
|
418
|
-
r5 = SyntaxNode.new(input, (index-1)...index) if r5 == true
|
419
|
-
r1 = r5
|
420
|
-
else
|
421
|
-
@index = i1
|
422
|
-
r1 = nil
|
423
|
-
end
|
387
|
+
@index = i0
|
388
|
+
r0 = nil
|
424
389
|
end
|
425
390
|
end
|
426
391
|
end
|
427
|
-
if r1
|
428
|
-
s0 << r1
|
429
|
-
else
|
430
|
-
break
|
431
|
-
end
|
432
|
-
end
|
433
|
-
if s0.empty?
|
434
|
-
@index = i0
|
435
|
-
r0 = nil
|
436
|
-
else
|
437
|
-
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
|
438
392
|
end
|
439
393
|
|
440
|
-
node_cache[:
|
394
|
+
node_cache[:expression_subset][start_index] = r0
|
441
395
|
|
442
396
|
r0
|
443
397
|
end
|
444
398
|
|
445
|
-
def
|
399
|
+
def _nt_expression
|
446
400
|
start_index = index
|
447
|
-
if node_cache[:
|
448
|
-
cached = node_cache[:
|
401
|
+
if node_cache[:expression].has_key?(index)
|
402
|
+
cached = node_cache[:expression][index]
|
449
403
|
if cached
|
450
|
-
node_cache[:
|
404
|
+
node_cache[:expression][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
451
405
|
@index = cached.interval.end
|
452
406
|
end
|
453
407
|
return cached
|
454
408
|
end
|
455
409
|
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
410
|
+
i0 = index
|
411
|
+
r1 = _nt_add
|
412
|
+
if r1
|
413
|
+
r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
|
414
|
+
r0 = r1
|
415
|
+
else
|
416
|
+
r2 = _nt_subtract
|
460
417
|
if r2
|
461
418
|
r2 = SyntaxNode.new(input, (index-1)...index) if r2 == true
|
462
|
-
|
419
|
+
r0 = r2
|
463
420
|
else
|
464
|
-
r3 =
|
421
|
+
r3 = _nt_multiply
|
465
422
|
if r3
|
466
423
|
r3 = SyntaxNode.new(input, (index-1)...index) if r3 == true
|
467
|
-
|
424
|
+
r0 = r3
|
468
425
|
else
|
469
|
-
r4 =
|
426
|
+
r4 = _nt_divide
|
470
427
|
if r4
|
471
428
|
r4 = SyntaxNode.new(input, (index-1)...index) if r4 == true
|
472
|
-
|
429
|
+
r0 = r4
|
473
430
|
else
|
474
|
-
r5 =
|
431
|
+
r5 = _nt_number_with_unit
|
475
432
|
if r5
|
476
433
|
r5 = SyntaxNode.new(input, (index-1)...index) if r5 == true
|
477
|
-
|
434
|
+
r0 = r5
|
478
435
|
else
|
479
|
-
r6 =
|
436
|
+
r6 = _nt_number
|
480
437
|
if r6
|
481
438
|
r6 = SyntaxNode.new(input, (index-1)...index) if r6 == true
|
482
|
-
|
439
|
+
r0 = r6
|
483
440
|
else
|
484
|
-
r7 =
|
441
|
+
r7 = _nt_name
|
485
442
|
if r7
|
486
443
|
r7 = SyntaxNode.new(input, (index-1)...index) if r7 == true
|
487
|
-
|
444
|
+
r0 = r7
|
488
445
|
else
|
489
|
-
r8 =
|
446
|
+
r8 = _nt_paren_expression
|
490
447
|
if r8
|
491
448
|
r8 = SyntaxNode.new(input, (index-1)...index) if r8 == true
|
492
|
-
|
449
|
+
r0 = r8
|
493
450
|
else
|
494
|
-
|
495
|
-
|
496
|
-
r9 = SyntaxNode.new(input, (index-1)...index) if r9 == true
|
497
|
-
r1 = r9
|
498
|
-
else
|
499
|
-
@index = i1
|
500
|
-
r1 = nil
|
501
|
-
end
|
451
|
+
@index = i0
|
452
|
+
r0 = nil
|
502
453
|
end
|
503
454
|
end
|
504
455
|
end
|
@@ -506,20 +457,9 @@ module OrigenSTIL
|
|
506
457
|
end
|
507
458
|
end
|
508
459
|
end
|
509
|
-
if r1
|
510
|
-
s0 << r1
|
511
|
-
else
|
512
|
-
break
|
513
|
-
end
|
514
|
-
end
|
515
|
-
if s0.empty?
|
516
|
-
@index = i0
|
517
|
-
r0 = nil
|
518
|
-
else
|
519
|
-
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
|
520
460
|
end
|
521
461
|
|
522
|
-
node_cache[:
|
462
|
+
node_cache[:expression][start_index] = r0
|
523
463
|
|
524
464
|
r0
|
525
465
|
end
|
@@ -946,7 +886,7 @@ module OrigenSTIL
|
|
946
886
|
elements[1]
|
947
887
|
end
|
948
888
|
|
949
|
-
def
|
889
|
+
def expression
|
950
890
|
elements[2]
|
951
891
|
end
|
952
892
|
|
@@ -986,7 +926,7 @@ module OrigenSTIL
|
|
986
926
|
r2 = _nt_s
|
987
927
|
s0 << r2
|
988
928
|
if r2
|
989
|
-
r3 =
|
929
|
+
r3 = _nt_expression
|
990
930
|
s0 << r3
|
991
931
|
if r3
|
992
932
|
r4 = _nt_s
|
@@ -7954,7 +7894,7 @@ module OrigenSTIL
|
|
7954
7894
|
|
7955
7895
|
module Name2
|
7956
7896
|
def to_ast
|
7957
|
-
text_value
|
7897
|
+
n :name, text_value
|
7958
7898
|
end
|
7959
7899
|
end
|
7960
7900
|
|
@@ -9032,6 +8972,16 @@ module OrigenSTIL
|
|
9032
8972
|
end
|
9033
8973
|
end
|
9034
8974
|
|
8975
|
+
module Number3
|
8976
|
+
def to_ast
|
8977
|
+
if text_value.to_f == text_value.to_i
|
8978
|
+
text_value.to_i
|
8979
|
+
else
|
8980
|
+
text_value.to_f
|
8981
|
+
end
|
8982
|
+
end
|
8983
|
+
end
|
8984
|
+
|
9035
8985
|
def _nt_number
|
9036
8986
|
start_index = index
|
9037
8987
|
if node_cache[:number].has_key?(index)
|
@@ -9048,6 +8998,8 @@ module OrigenSTIL
|
|
9048
8998
|
if r1
|
9049
8999
|
r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
|
9050
9000
|
r0 = r1
|
9001
|
+
r0.extend(Number3)
|
9002
|
+
r0.extend(Number3)
|
9051
9003
|
else
|
9052
9004
|
i2, s2 = index, []
|
9053
9005
|
r3 = _nt_signed_integer
|
@@ -9076,6 +9028,8 @@ module OrigenSTIL
|
|
9076
9028
|
if r2
|
9077
9029
|
r2 = SyntaxNode.new(input, (index-1)...index) if r2 == true
|
9078
9030
|
r0 = r2
|
9031
|
+
r0.extend(Number3)
|
9032
|
+
r0.extend(Number3)
|
9079
9033
|
else
|
9080
9034
|
i6, s6 = index, []
|
9081
9035
|
r7 = _nt_signed_integer
|
@@ -9104,6 +9058,8 @@ module OrigenSTIL
|
|
9104
9058
|
if r6
|
9105
9059
|
r6 = SyntaxNode.new(input, (index-1)...index) if r6 == true
|
9106
9060
|
r0 = r6
|
9061
|
+
r0.extend(Number3)
|
9062
|
+
r0.extend(Number3)
|
9107
9063
|
else
|
9108
9064
|
i10, s10 = index, []
|
9109
9065
|
r11 = _nt_signed_integer
|
@@ -9146,6 +9102,8 @@ module OrigenSTIL
|
|
9146
9102
|
if r10
|
9147
9103
|
r10 = SyntaxNode.new(input, (index-1)...index) if r10 == true
|
9148
9104
|
r0 = r10
|
9105
|
+
r0.extend(Number3)
|
9106
|
+
r0.extend(Number3)
|
9149
9107
|
else
|
9150
9108
|
@index = i0
|
9151
9109
|
r0 = nil
|
data/lib/origen_stil.rb
CHANGED
@@ -22,11 +22,12 @@ module OrigenSTIL
|
|
22
22
|
end
|
23
23
|
|
24
24
|
module Processor
|
25
|
-
autoload :Base,
|
26
|
-
autoload :Pins,
|
27
|
-
autoload :PinGroups,
|
28
|
-
autoload :Pattern,
|
29
|
-
autoload :Timesets,
|
25
|
+
autoload :Base, 'origen_stil/processor/base'
|
26
|
+
autoload :Pins, 'origen_stil/processor/pins'
|
27
|
+
autoload :PinGroups, 'origen_stil/processor/pin_groups'
|
28
|
+
autoload :Pattern, 'origen_stil/processor/pattern'
|
29
|
+
autoload :Timesets, 'origen_stil/processor/timesets'
|
30
|
+
autoload :Expression, 'origen_stil/processor/expression'
|
30
31
|
end
|
31
32
|
|
32
33
|
autoload :Pattern, 'origen_stil/pattern'
|
@@ -63,6 +64,11 @@ module OrigenSTIL
|
|
63
64
|
def self.patterns
|
64
65
|
@patterns ||= {}
|
65
66
|
end
|
67
|
+
|
68
|
+
# @api private
|
69
|
+
def self.unquote(str)
|
70
|
+
str.gsub(/\A("|')|("|')\Z/, '')
|
71
|
+
end
|
66
72
|
end
|
67
73
|
|
68
74
|
STIL = OrigenSTIL unless defined?(STIL)
|
data/lib/origen_stil/pattern.rb
CHANGED
@@ -8,23 +8,31 @@ module OrigenSTIL
|
|
8
8
|
fail "STIL source file not found: #{path}"
|
9
9
|
end
|
10
10
|
@path = path
|
11
|
+
@loop = Struct.new(:id, :count, :status, :source_line_number, :number_of_lines, :braces, :lines)
|
12
|
+
@n = 0
|
11
13
|
end
|
12
14
|
|
13
15
|
def execute(options = {})
|
14
|
-
|
16
|
+
options = {
|
17
|
+
set_timesets: false,
|
18
|
+
add_pins: true
|
19
|
+
}.merge(options)
|
20
|
+
@exec_options = options
|
21
|
+
@n = 0
|
22
|
+
add_pins if options[:add_pins]
|
15
23
|
Processor::Pattern.new.run(ast) do |pattern_name|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
i = 0
|
25
|
+
open = false
|
26
|
+
File.foreach(path) do |line|
|
27
|
+
if open
|
28
|
+
# Stop at next pattern or EOF
|
29
|
+
break if line =~ /^\s*Pattern/
|
30
|
+
|
31
|
+
consume_line(line, i)
|
32
|
+
else
|
33
|
+
open = true if line =~ /^\s*Pattern "?'?#{pattern_name}"?'?\s*{/
|
26
34
|
end
|
27
|
-
|
35
|
+
i += 1
|
28
36
|
end
|
29
37
|
end
|
30
38
|
end
|
@@ -69,53 +77,128 @@ module OrigenSTIL
|
|
69
77
|
@timesets ||= Processor::Timesets.new.run(ast, options)
|
70
78
|
end
|
71
79
|
|
72
|
-
|
73
|
-
|
74
|
-
#
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
80
|
+
private
|
81
|
+
|
82
|
+
# vector[:repeat].cycles
|
83
|
+
def consume_line(line, source_line_number)
|
84
|
+
if @open_loop
|
85
|
+
execute_loop(line)
|
86
|
+
else
|
87
|
+
if line =~ /(.*)(?:^|.*:)\s*Loop\s+(\d+)(.*)/
|
88
|
+
# :id, :count, :status, :source_line_number, :number_of_lines, :braces, :lines)
|
89
|
+
@open_loop = @loop.new(Regexp.last_match(1), Regexp.last_match(2).to_i, :pending, source_line_number, 0, 0, [])
|
90
|
+
execute_loop(Regexp.last_match(3))
|
91
|
+
|
92
|
+
else
|
93
|
+
execute_line(line, source_line_number)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def execute_loop(line)
|
99
|
+
# This is the number of lines that the source code spans, not necessarily the number
|
100
|
+
# of active lines in the loop
|
101
|
+
@open_loop.number_of_lines += 1
|
102
|
+
content = ''
|
103
|
+
comment = nil
|
104
|
+
line.each_char do |c|
|
105
|
+
# Stop processing the remainder if the line when a comment is encountered
|
106
|
+
if c == '/'
|
107
|
+
break if comment == '/'
|
108
|
+
comment = '/'
|
109
|
+
next
|
110
|
+
else
|
111
|
+
comment = nil
|
112
|
+
end
|
113
|
+
if @open_loop.status == :pending
|
114
|
+
next if c == ' ' || c == "\t" || c == "\n"
|
115
|
+
if c == '{'
|
116
|
+
@open_loop.status = :open
|
117
|
+
@open_loop.braces += 1
|
118
|
+
else
|
119
|
+
fail "No start of loop character '{' around line #{@open_loop.source_line_number}"
|
120
|
+
end
|
121
|
+
elsif @open_loop.status == :open
|
122
|
+
if c == '{'
|
123
|
+
@open_loop.braces += 1
|
124
|
+
content += c
|
125
|
+
elsif c == '}'
|
126
|
+
@open_loop.braces -= 1
|
127
|
+
if @open_loop.braces == 0
|
128
|
+
@open_loop.status = :done
|
129
|
+
content = content.strip
|
130
|
+
unless content.empty?
|
131
|
+
@open_loop.lines << content
|
132
|
+
content = ''
|
133
|
+
end
|
134
|
+
else
|
135
|
+
content += c
|
104
136
|
end
|
105
|
-
|
106
|
-
|
137
|
+
else
|
138
|
+
content += c
|
107
139
|
end
|
108
140
|
else
|
109
|
-
|
141
|
+
content += c
|
110
142
|
end
|
111
143
|
end
|
144
|
+
|
145
|
+
if @open_loop.status == :done
|
146
|
+
lp = @open_loop
|
147
|
+
@open_loop = nil
|
148
|
+
# If loop being used like a repeat
|
149
|
+
if lp.lines.size == 1 && lp.lines.first =~ /(?:^|.*:)\s*(?:V|Vector)\s+{(.*)}/
|
150
|
+
execute_line(lp.lines.first, lp.source_line_number, lp.count)
|
151
|
+
else
|
152
|
+
tester.loop_vectors "lp#{@n}", lp.count do
|
153
|
+
lp.lines.each { |line| consume_line(line, lp.source_line_number) }
|
154
|
+
end
|
155
|
+
end
|
156
|
+
# Consume any remaining content on the line after the loop closed
|
157
|
+
unless content.strip.empty?
|
158
|
+
consume_line(content, lp.source_line_number + lp.number_of_lines - 1)
|
159
|
+
end
|
160
|
+
else
|
161
|
+
content = content.strip
|
162
|
+
@open_loop.lines << content unless content.empty?
|
163
|
+
end
|
112
164
|
end
|
113
165
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
166
|
+
# Sends any understood operations from the given line to the current tester
|
167
|
+
def execute_line(line, source_line_number, cycles = 1)
|
168
|
+
# These are in order of more likely occurrence for speed, i.e. assume that most
|
169
|
+
# pattern lines are vectors...
|
170
|
+
if line =~ /(?:^|.*:)\s*(?:V|Vector)\s+{(.*)}/
|
171
|
+
Regexp.last_match(1).strip.split(';').each do |assignment|
|
172
|
+
assignment = assignment.split(/\s*=\s*/)
|
173
|
+
pin = dut.pins(OrigenSTIL.unquote(assignment[0]))
|
174
|
+
data = assignment[1].gsub(/\s+/, '')
|
175
|
+
pin.vector_formatted_value = data
|
176
|
+
end
|
177
|
+
cycles.cycles
|
178
|
+
|
179
|
+
# Pattern comments
|
180
|
+
elsif line =~ /^\s*Ann\s*{\*\s*(.*)\s*\*}/
|
181
|
+
cc Regexp.last_match(1)
|
182
|
+
|
183
|
+
# Source comments
|
184
|
+
elsif line =~ /\s*\/\/.*/
|
185
|
+
# Just ignore source comments
|
186
|
+
|
187
|
+
# Change of timeset
|
188
|
+
elsif line =~ /(?:^|.*:)\s*(?:W|WaveformTable)\s+(.*)\s*;/
|
189
|
+
if @exec_options[:set_timesets]
|
190
|
+
timeset = OrigenSTIL.unquote(Regexp.last_match(1))
|
191
|
+
if timeset != @current_timeset
|
192
|
+
tester.set_timeset(timeset, timesets[timeset][:period_in_ns])
|
193
|
+
@current_timeset = timeset
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
else
|
198
|
+
line = line.strip
|
199
|
+
unless line.empty? || line == '}' # End of pattern
|
200
|
+
Origen.log.warning "Skipped Pattern line #{source_line_number}: #{line}"
|
201
|
+
end
|
119
202
|
end
|
120
203
|
end
|
121
204
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module OrigenSTIL
|
2
|
+
module Processor
|
3
|
+
# Evaluates an expression to a final answer
|
4
|
+
class Expression < Base
|
5
|
+
# Given node should be a top-level expression node, like a :time_expr
|
6
|
+
def run(node, options = {})
|
7
|
+
process(node).value
|
8
|
+
end
|
9
|
+
|
10
|
+
def on_number_with_unit(node)
|
11
|
+
val = node.find(:value).value
|
12
|
+
if p = node.find(:prefix)
|
13
|
+
case p.value
|
14
|
+
when 'E'
|
15
|
+
val = val * 1_000_000_000_000_000_000
|
16
|
+
when 'P'
|
17
|
+
val = val * 1_000_000_000_000_000
|
18
|
+
when 'T'
|
19
|
+
val = val * 1_000_000_000_000
|
20
|
+
when 'G'
|
21
|
+
val = val * 1_000_000_000
|
22
|
+
when 'M'
|
23
|
+
val = val * 1_000_000
|
24
|
+
when 'k'
|
25
|
+
val = val * 1000
|
26
|
+
when 'm'
|
27
|
+
val = val / 1000.0
|
28
|
+
when 'u'
|
29
|
+
val = val / 1_000_000.0
|
30
|
+
when 'n'
|
31
|
+
val = val / 1_000_000_000.0
|
32
|
+
when 'p'
|
33
|
+
val = val / 1_000_000_000_000.0
|
34
|
+
when 'f'
|
35
|
+
val = val / 1_000_000_000_000_000.0
|
36
|
+
when 'a'
|
37
|
+
val = val / 1_000_000_000_000_000_000.0
|
38
|
+
else
|
39
|
+
fail "Unknown number prefix #{p.value}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
val
|
43
|
+
end
|
44
|
+
|
45
|
+
def on_parens(node)
|
46
|
+
process_all(node.children).first
|
47
|
+
end
|
48
|
+
|
49
|
+
def on_multiply(node)
|
50
|
+
a, b = *process_all(node.children)
|
51
|
+
a * b
|
52
|
+
end
|
53
|
+
|
54
|
+
def on_divide(node)
|
55
|
+
a, b = *process_all(node.children)
|
56
|
+
a / (b * 1.0)
|
57
|
+
end
|
58
|
+
|
59
|
+
def on_add(node)
|
60
|
+
a, b = *process_all(node.children)
|
61
|
+
a + b
|
62
|
+
end
|
63
|
+
|
64
|
+
def on_subtract(node)
|
65
|
+
a, b = *process_all(node.children)
|
66
|
+
a - b
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -19,6 +19,7 @@ module OrigenSTIL
|
|
19
19
|
|
20
20
|
def on_pattern_burst(node)
|
21
21
|
name, pat_list = *node
|
22
|
+
name = name.value if name.try(:type) == :name
|
22
23
|
if pat_list
|
23
24
|
@bursts[name] = []
|
24
25
|
@current_burst = @bursts[name]
|
@@ -27,7 +28,9 @@ module OrigenSTIL
|
|
27
28
|
end
|
28
29
|
|
29
30
|
def on_pat_list_item(node)
|
30
|
-
|
31
|
+
name = node.to_a[0]
|
32
|
+
name = name.value if name.try(:type) == :name
|
33
|
+
@current_burst << name
|
31
34
|
end
|
32
35
|
end
|
33
36
|
end
|
@@ -11,25 +11,57 @@ module OrigenSTIL
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
+
def on_signal_groups(node)
|
15
|
+
groups = node.children
|
16
|
+
if groups.first.type == :name
|
17
|
+
groups = groups.dup
|
18
|
+
# Not doing anything with named groups currently
|
19
|
+
@current_signal_group_domain = groups.shift.value
|
20
|
+
groups.freeze
|
21
|
+
Origen.log.warning "Signal groups for domain \"#{@current_signal_group_domain}\" are being ignored (support for named signal groups is not implemented yet)"
|
22
|
+
# process_all(groups)
|
23
|
+
else
|
24
|
+
@current_signal_group_domain = nil
|
25
|
+
process_all(groups)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
14
29
|
def on_signal_group(node)
|
15
30
|
name, expr = *node
|
31
|
+
name = OrigenSTIL.unquote(name.value)
|
32
|
+
@current_signal_group = name
|
16
33
|
unless model.has_pin?(name)
|
17
34
|
ids = process(expr).to_a[0]
|
18
35
|
model.add_pin_group name.to_sym, *ids
|
19
36
|
end
|
20
37
|
end
|
21
38
|
|
39
|
+
def on_name(node)
|
40
|
+
id = node.value
|
41
|
+
if model.has_pin?(id)
|
42
|
+
# Expand any references to another pin group
|
43
|
+
id = id.to_sym
|
44
|
+
if dut.pin_groups.ids.map(&:to_sym).include?(id)
|
45
|
+
model.pin(id).map(&:id)
|
46
|
+
else
|
47
|
+
[id]
|
48
|
+
end
|
49
|
+
else
|
50
|
+
fail "Pin #{id} referenced at #{node.file}:#{node.line_number} but DUT does not have this pin/pin_group"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
22
54
|
def on_add(node)
|
23
55
|
lhs, rhs = *node
|
24
56
|
Array(process(lhs)) + Array(process(rhs))
|
25
57
|
end
|
26
58
|
|
27
59
|
def on_subtract(node)
|
28
|
-
fail '
|
60
|
+
fail 'Subtraction in pin groups is not supported yet'
|
29
61
|
end
|
30
62
|
|
31
|
-
def
|
32
|
-
|
63
|
+
def on_parens(node)
|
64
|
+
process_all(node.children).first
|
33
65
|
end
|
34
66
|
end
|
35
67
|
end
|
@@ -11,6 +11,7 @@ module OrigenSTIL
|
|
11
11
|
|
12
12
|
def on_signal(node)
|
13
13
|
name, direction = *node
|
14
|
+
name = OrigenSTIL.unquote(name)
|
14
15
|
if direction == 'In'
|
15
16
|
direction = :input
|
16
17
|
elsif direction == 'Out'
|
@@ -36,6 +37,12 @@ module OrigenSTIL
|
|
36
37
|
end
|
37
38
|
end
|
38
39
|
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def unquote(str)
|
44
|
+
str.gsub(/\A("|')|("|')\Z/, '')
|
45
|
+
end
|
39
46
|
end
|
40
47
|
end
|
41
48
|
end
|
@@ -11,9 +11,15 @@ module OrigenSTIL
|
|
11
11
|
|
12
12
|
def on_waveform_table(node)
|
13
13
|
name = node.to_a[0]
|
14
|
-
|
15
|
-
period = node.find(:period)
|
14
|
+
name = name.value if name.try(:type) == :name
|
16
15
|
@timesets[name] = {}
|
16
|
+
if period = node.find(:period)
|
17
|
+
@timesets[name][:period_in_ns] = process_all(period.children).first * 1_000_000_000
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def on_time_expr(node)
|
22
|
+
Expression.new.run(node)
|
17
23
|
end
|
18
24
|
end
|
19
25
|
end
|
data/pattern/example3.rb
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: origen_stil
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen McGinty
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: origen
|
@@ -59,7 +59,6 @@ executables: []
|
|
59
59
|
extensions: []
|
60
60
|
extra_rdoc_files: []
|
61
61
|
files:
|
62
|
-
- bin/fix_my_workspace
|
63
62
|
- config/application.rb
|
64
63
|
- config/boot.rb
|
65
64
|
- config/commands.rb
|
@@ -68,6 +67,7 @@ files:
|
|
68
67
|
- lib/origen_stil.rb
|
69
68
|
- lib/origen_stil/pattern.rb
|
70
69
|
- lib/origen_stil/processor/base.rb
|
70
|
+
- lib/origen_stil/processor/expression.rb
|
71
71
|
- lib/origen_stil/processor/pattern.rb
|
72
72
|
- lib/origen_stil/processor/pin_groups.rb
|
73
73
|
- lib/origen_stil/processor/pins.rb
|
@@ -75,6 +75,7 @@ files:
|
|
75
75
|
- lib/origen_stil/syntax/node.rb
|
76
76
|
- lib/origen_stil/syntax/parser.rb
|
77
77
|
- lib/tasks/origen_stil.rake
|
78
|
+
- pattern/example3.rb
|
78
79
|
- templates/web/index.md.erb
|
79
80
|
- templates/web/layouts/_basic.html.erb
|
80
81
|
- templates/web/partials/_navbar.html.erb
|
@@ -98,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
98
99
|
version: 1.8.11
|
99
100
|
requirements: []
|
100
101
|
rubyforge_project:
|
101
|
-
rubygems_version: 2.7.
|
102
|
+
rubygems_version: 2.7.7
|
102
103
|
signing_key:
|
103
104
|
specification_version: 4
|
104
105
|
summary: Helpers to consume and generate test IP in STIL format (IEEE 1450)
|
data/bin/fix_my_workspace
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
$VERBOSE = nil # Don't care about world writable dir warnings and the like
|
3
|
-
|
4
|
-
if $_fix_my_workspace_version_check
|
5
|
-
$_fix_my_workspace_version = '0.7.0'
|
6
|
-
else
|
7
|
-
if File.exist?(File.expand_path('../../lib/origen.rb', __FILE__))
|
8
|
-
# If this script is being run from within an origen-core workspace, use that Origen-core,
|
9
|
-
# not the system-installed origen-core version.
|
10
|
-
$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
|
11
|
-
require 'origen'
|
12
|
-
else
|
13
|
-
# Use system-installed Origen (the gem in system Ruby)
|
14
|
-
require 'origen'
|
15
|
-
end
|
16
|
-
|
17
|
-
if !Origen.site_config.gem_manage_bundler
|
18
|
-
puts 'Sorry but you have opted to manage Bundler yourself via your Origen site config, and this means'
|
19
|
-
puts 'that I cannot make certain assumptions about how your workspace is configured.'
|
20
|
-
puts 'You will need to either resolve this problem yourself, or else change the value of'
|
21
|
-
puts 'gem_mange_bundler to true.'
|
22
|
-
puts 'See here for more details on how to do that: http://origen-sdk.org/origen/guides/starting/company/'
|
23
|
-
|
24
|
-
else
|
25
|
-
ENV['BUNDLE_GEMFILE'] = File.join(Origen.root, 'Gemfile')
|
26
|
-
ENV['BUNDLE_PATH'] = File.expand_path(Origen.site_config.gem_install_dir)
|
27
|
-
ENV['BUNDLE_BIN'] = File.join(Origen.root, 'lbin')
|
28
|
-
|
29
|
-
# Force copy system gems to local gems
|
30
|
-
if Origen.site_config.gem_use_from_system
|
31
|
-
local_gem_dir = "#{ENV['BUNDLE_PATH']}/ruby/#{Pathname.new(Gem.dir).basename}"
|
32
|
-
gem_dir = Pathname.new(Gem.dir)
|
33
|
-
|
34
|
-
Origen.site_config.gem_use_from_system.each do |gem, version|
|
35
|
-
begin
|
36
|
-
# This will raise an error if the system doesn't have this gem installed, that
|
37
|
-
# will be rescued below
|
38
|
-
spec = Gem::Specification.find_by_name(gem, version)
|
39
|
-
|
40
|
-
local_dir = File.join(local_gem_dir, Pathname.new(spec.gem_dir).relative_path_from(gem_dir))
|
41
|
-
FileUtils.mkdir_p local_dir
|
42
|
-
FileUtils.cp_r("#{spec.gem_dir}/.", local_dir)
|
43
|
-
|
44
|
-
local_file = Pathname.new(File.join(local_gem_dir, Pathname.new(spec.cache_file).relative_path_from(gem_dir)))
|
45
|
-
FileUtils.mkdir_p local_file.dirname
|
46
|
-
FileUtils.cp(spec.cache_file, local_file)
|
47
|
-
|
48
|
-
if spec.extension_dir && File.exist?(spec.extension_dir)
|
49
|
-
local_dir = File.join(local_gem_dir, Pathname.new(spec.extension_dir).relative_path_from(gem_dir))
|
50
|
-
FileUtils.mkdir_p local_dir
|
51
|
-
FileUtils.cp_r("#{spec.extension_dir}/.", local_dir)
|
52
|
-
end
|
53
|
-
|
54
|
-
local_file = Pathname.new(File.join(local_gem_dir, Pathname.new(spec.spec_file).relative_path_from(gem_dir)))
|
55
|
-
FileUtils.mkdir_p local_file.dirname
|
56
|
-
FileUtils.cp(spec.spec_file, local_file)
|
57
|
-
|
58
|
-
rescue Gem::LoadError
|
59
|
-
# This just means that one of the gems that should be copied from the system
|
60
|
-
# was not actually installed in the system, so nothing we can do about that here
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
# Delete lbin
|
66
|
-
FileUtils.rm_rf(ENV['BUNDLE_BIN']) if File.exist?(ENV['BUNDLE_BIN'])
|
67
|
-
|
68
|
-
# Run bundler with correct switches
|
69
|
-
cmd = "bundle install --gemfile #{ENV['BUNDLE_GEMFILE']} --binstubs #{ENV['BUNDLE_BIN']} --path #{ENV['BUNDLE_PATH']}"
|
70
|
-
`chmod o-w #{Origen.root}` # Stops some annoying world writable warnings during install
|
71
|
-
`chmod o-w #{Origen.root}/bin` if File.exist?("#{Origen.root}/bin")
|
72
|
-
`chmod o-w #{Origen.root}/.bin` if File.exist?("#{Origen.root}/.bin")
|
73
|
-
|
74
|
-
# Try again, this time updating the bundle
|
75
|
-
if system(cmd)
|
76
|
-
fixed = true
|
77
|
-
elsif system 'bundle update'
|
78
|
-
fixed = true
|
79
|
-
end
|
80
|
-
|
81
|
-
if File.exist?(ENV['BUNDLE_BIN'])
|
82
|
-
`chmod o-w #{ENV['BUNDLE_BIN']}`
|
83
|
-
|
84
|
-
# Make .bat versions of all executables, Bundler should really be doing this when running
|
85
|
-
# on windows
|
86
|
-
if Origen.os.windows?
|
87
|
-
Dir.glob("#{ENV['BUNDLE_BIN']}/*").each do |bin|
|
88
|
-
unless bin =~ /.bat$/
|
89
|
-
bat = "#{bin}.bat"
|
90
|
-
unless File.exist?(bat)
|
91
|
-
File.open(bat, 'w') { |f| f.write('@"ruby.exe" "%~dpn0" %*') }
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
system 'origen -v' if fixed
|
99
|
-
end
|
100
|
-
end
|