origen_sim 0.20.6 → 0.21.0
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/config/commands.rb +27 -1
- data/config/shared_commands.rb +9 -2
- data/config/version.rb +2 -2
- data/ext/bridge.c +27 -13
- data/ext/common.h +1 -0
- data/ext/defines.h.erb +3 -0
- data/lib/origen_sim/commands/build.rb +191 -92
- data/lib/origen_sim/origen/pins/pin.rb +4 -4
- data/lib/origen_sim/origen/top_level.rb +17 -8
- data/lib/origen_sim/origen_testers/api.rb +1 -1
- data/lib/origen_sim/simulator.rb +129 -21
- data/lib/origen_sim/tester.rb +61 -25
- data/lib/origen_sim.rb +13 -0
- data/lib/origen_sim_dev/dut.rb +4 -0
- data/pattern/test.rb +9 -2
- data/templates/origen_guides/simulation/patterns.md.erb +8 -0
- data/templates/probe.tcl.erb +1 -2
- data/templates/rtl_v/origen.v.erb +104 -34
- metadata +5 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 33d839d0d39003f94420f011ba006246dc9ff62bbf2435fd5ae269fe4d1f459c
|
4
|
+
data.tar.gz: 9a99d9f31fe6535f00df5feb82f78a6a2e90f4af70e38f685c37af61592be7e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75f75689510b1978d0650c6de92267acb4386b25a5f6d528f253ce282406d406b7c5e4942ed26d6d8188e9a49b337d34069343834fec8c0e28334d7caf36b765
|
7
|
+
data.tar.gz: 1e5e23dae2c4e20a5b969cd2322e9aafde47988a468f69f958ba602fbb74e2b4bfc083d2b1752ae481f4b45e8475f083bf54d3ab661c3f211ccf7908bdce0222
|
data/config/commands.rb
CHANGED
@@ -23,13 +23,36 @@ when "sim:build_example"
|
|
23
23
|
ARGV.delete_at(index)
|
24
24
|
Origen.environment.temporary = ARGV.delete_at(index)
|
25
25
|
end
|
26
|
+
if ['cadence'].include?(Origen.environment.name)
|
27
|
+
cmd += ' --define ORIGEN_SIM_CADENCE'
|
28
|
+
elsif ['synopsys', 'synopsys_verdi'].include?(Origen.environment.name)
|
29
|
+
cmd += ' --define ORIGEN_SIM_SYNOPSIS'
|
30
|
+
elsif ['icarus'].include?(Origen.environment.name)
|
31
|
+
cmd += ' --define ORIGEN_SIM_ICARUS'
|
32
|
+
end
|
33
|
+
|
34
|
+
clean = false
|
35
|
+
if ARGV.include?('--clean')
|
36
|
+
ARGV.delete_at(ARGV.index('--clean'))
|
37
|
+
clean = true
|
38
|
+
end
|
26
39
|
cmd += ' ' + ARGV.join(' ') unless ARGV.empty?
|
40
|
+
|
41
|
+
|
27
42
|
# Enable wreal pins in the DUT RTL
|
28
43
|
cmd += ' --define ORIGEN_WREAL' if ARGV.include?('--wreal')
|
44
|
+
#cmd += " --define ORIGEN_WREALAVG --sv --force_pin_type vdd:real --force_pin_type ana:real --passthrough \"-sysv_ext +.v -define ORIGEN_WREALAVG +define+ORIGEN_SIM_CADENCE #{Origen.app.root}/top.scs\"" if ARGV.include?('--wrealavg')
|
45
|
+
cmd += " --define ORIGEN_WREALAVG --sv --force_pin_type vdd:real --force_pin_type ana:real --passthrough \"+define+ORIGEN_SIM_SYNOPSIS\"" if ARGV.include?('--wrealavg')
|
29
46
|
output = `#{cmd}`
|
30
47
|
puts output
|
31
48
|
Origen.load_target
|
32
49
|
dir = "simulation/default/#{tester.simulator.config[:vendor]}"
|
50
|
+
|
51
|
+
if clean
|
52
|
+
puts "Cleaning directory: #{dir}"
|
53
|
+
FileUtils.rm_r(dir)
|
54
|
+
end
|
55
|
+
|
33
56
|
FileUtils.mkdir_p(dir)
|
34
57
|
Dir.chdir dir do
|
35
58
|
case tester.simulator.config[:vendor]
|
@@ -42,7 +65,10 @@ when "sim:build_example"
|
|
42
65
|
|
43
66
|
when :cadence
|
44
67
|
output =~ /\n(.*irun .*)\n/
|
45
|
-
|
68
|
+
compile_cmd = $1.gsub('stub', 'dut1')
|
69
|
+
compile_cmd.gsub!('origen.v', 'origen.sv') if cmd.include?('--define ORIGEN_SV')
|
70
|
+
puts compile_cmd.green
|
71
|
+
system compile_cmd
|
46
72
|
|
47
73
|
when :synopsys
|
48
74
|
if tester.simulator.config[:verdi]
|
data/config/shared_commands.rb
CHANGED
@@ -48,7 +48,7 @@ when "sim:unpack"
|
|
48
48
|
when "sim:run"
|
49
49
|
OrigenSim.run_source(ARGV[0])
|
50
50
|
exit 0
|
51
|
-
|
51
|
+
|
52
52
|
#when "sim:list"
|
53
53
|
# require "#{Origen.root!}/lib/origen_sim/commands/pack"
|
54
54
|
# OrigenSim::Commands::Pack.list
|
@@ -60,7 +60,14 @@ else
|
|
60
60
|
sim:co Checkout a simulation snapshot
|
61
61
|
sim:pack Packs the snapshot into a compressed directory
|
62
62
|
sim:unpack Unpacks a snapshot
|
63
|
-
sim:list List the available snapshot packs
|
64
63
|
EOT
|
64
|
+
# sim:list List the available snapshot packs
|
65
|
+
|
66
|
+
if OrigenTesters.respond_to?(:decompile)
|
67
|
+
@plugin_commands << <<-EOT
|
68
|
+
sim:run Simulates the given source without using any of Origen's 'startup' collateral.
|
69
|
+
Requires: a decompiler for the given source and timing information setup beforehand.
|
70
|
+
EOT
|
71
|
+
end
|
65
72
|
|
66
73
|
end
|
data/config/version.rb
CHANGED
data/ext/bridge.c
CHANGED
@@ -29,6 +29,7 @@ typedef struct Pin {
|
|
29
29
|
int compare_wave_pos; // Position of the pin in the compare_wave's active pin array
|
30
30
|
int index; // The pin's index in the pins array
|
31
31
|
int previous_state; // Used to keep track of whether the pin was previously driving or comparing
|
32
|
+
int drive_data; // Used to hold the new drive data for this pin until needed by the drive wave
|
32
33
|
bool capture_en; // Used to indicated when compare data should be captured instead of compared
|
33
34
|
bool present; // Set to true if the pin is present in the testbench
|
34
35
|
} Pin;
|
@@ -108,13 +109,14 @@ static void define_pin(char * name, char * pin_ix, char * drive_wave_ix, char *
|
|
108
109
|
(*pin).compare_wave = atoi(compare_wave_ix);
|
109
110
|
(*pin).previous_state = 0;
|
110
111
|
(*pin).capture_en = false;
|
112
|
+
(*pin).drive_data = 0;
|
111
113
|
|
112
114
|
|
113
|
-
char * driver = (char *) malloc(strlen(name) +
|
115
|
+
char * driver = (char *) malloc(strlen(name) + ORIGEN_SIM_TB_NAME_LEN + 7); // testbench name + . + 'pins.' + '\0'
|
114
116
|
strcpy(driver, ORIGEN_SIM_TESTBENCH_CAT("pins."));
|
115
117
|
strcat(driver, name);
|
116
118
|
|
117
|
-
char * data = (char *) malloc(strlen(driver) +
|
119
|
+
char * data = (char *) malloc(strlen(driver) + 6);
|
118
120
|
strcpy(data, driver);
|
119
121
|
strcat(data, ".data");
|
120
122
|
(*pin).data = vpi_handle_by_name(data, NULL);
|
@@ -127,25 +129,25 @@ static void define_pin(char * name, char * pin_ix, char * drive_wave_ix, char *
|
|
127
129
|
(*pin).present = true;
|
128
130
|
}
|
129
131
|
|
130
|
-
char * drive = (char *) malloc(strlen(driver) +
|
132
|
+
char * drive = (char *) malloc(strlen(driver) + 7);
|
131
133
|
strcpy(drive, driver);
|
132
134
|
strcat(drive, ".drive");
|
133
135
|
(*pin).drive = vpi_handle_by_name(drive, NULL);
|
134
136
|
free(drive);
|
135
137
|
|
136
|
-
char * force = (char *) malloc(strlen(driver) +
|
138
|
+
char * force = (char *) malloc(strlen(driver) + 12);
|
137
139
|
strcpy(force, driver);
|
138
140
|
strcat(force, ".force_data");
|
139
141
|
(*pin).force_data = vpi_handle_by_name(force, NULL);
|
140
142
|
free(force);
|
141
143
|
|
142
|
-
char * compare = (char *) malloc(strlen(driver) +
|
144
|
+
char * compare = (char *) malloc(strlen(driver) + 9);
|
143
145
|
strcpy(compare, driver);
|
144
146
|
strcat(compare, ".compare");
|
145
147
|
(*pin).compare = vpi_handle_by_name(compare, NULL);
|
146
148
|
free(compare);
|
147
149
|
|
148
|
-
char * capture = (char *) malloc(strlen(driver) +
|
150
|
+
char * capture = (char *) malloc(strlen(driver) + 9);
|
149
151
|
strcpy(capture, driver);
|
150
152
|
strcat(capture, ".capture");
|
151
153
|
(*pin).capture = vpi_handle_by_name(capture, NULL);
|
@@ -326,9 +328,15 @@ static void drive_pin(char * index, char * val) {
|
|
326
328
|
s_vpi_value v = {vpiIntVal, {0}};
|
327
329
|
|
328
330
|
if ((*pin).present) {
|
331
|
+
// Store the pin drive data to be applied at the data edge
|
332
|
+
(*pin).drive_data = (val[0] - '0');
|
333
|
+
|
329
334
|
// Apply the data value to the pin's driver
|
330
|
-
|
331
|
-
|
335
|
+
if (is_drive_whole_cycle(pin)) {
|
336
|
+
v.value.integer = (*pin).drive_data;
|
337
|
+
vpi_put_value((*pin).data, &v, NULL, vpiNoDelay);
|
338
|
+
}
|
339
|
+
|
332
340
|
// Make sure not comparing
|
333
341
|
v.value.integer = 0;
|
334
342
|
vpi_put_value((*pin).compare, &v, NULL, vpiNoDelay);
|
@@ -431,6 +439,7 @@ static void dont_care_pin(char * index) {
|
|
431
439
|
PLI_INT32 apply_wave_event_cb(p_cb_data data) {
|
432
440
|
s_vpi_value v = {vpiIntVal, {0}};
|
433
441
|
s_vpi_value v2 = {vpiIntVal, {0}};
|
442
|
+
s_vpi_value v3 = {vpiIntVal, {0}};
|
434
443
|
|
435
444
|
int * wave_ix = (int*)(&(data->user_data[0]));
|
436
445
|
int * event_ix = (int*)(&(data->user_data[sizeof(int)]));
|
@@ -486,6 +495,11 @@ PLI_INT32 apply_wave_event_cb(p_cb_data data) {
|
|
486
495
|
case 'D' :
|
487
496
|
d = 0;
|
488
497
|
on = 1;
|
498
|
+
// Apply the data value to the pin's driver
|
499
|
+
for (int i = 0; i < (*wave).active_pin_count; i++) {
|
500
|
+
v3.value.integer = (*(*wave).active_pins[i]).drive_data;
|
501
|
+
vpi_put_value((*(*wave).active_pins[i]).data, &v3, NULL, vpiNoDelay);
|
502
|
+
}
|
489
503
|
break;
|
490
504
|
case 'X' :
|
491
505
|
d = 0;
|
@@ -750,7 +764,7 @@ PLI_INT32 bridge_wait_for_msg(p_cb_data data) {
|
|
750
764
|
// Set Pattern Name
|
751
765
|
// a^atd_ramp_25mhz
|
752
766
|
case 'a' :
|
753
|
-
handle = vpi_handle_by_name(ORIGEN_SIM_TESTBENCH_CAT("
|
767
|
+
handle = vpi_handle_by_name(ORIGEN_SIM_TESTBENCH_CAT(ORIGEN_SIM_DEBUG_MODULE_CAT("pattern")), NULL);
|
754
768
|
arg1 = strtok(NULL, "^");
|
755
769
|
|
756
770
|
v.format = vpiStringVal;
|
@@ -786,7 +800,7 @@ PLI_INT32 bridge_wait_for_msg(p_cb_data data) {
|
|
786
800
|
arg1 = strtok(NULL, "^");
|
787
801
|
arg2 = strtok(NULL, "^");
|
788
802
|
|
789
|
-
strcpy(comment, ORIGEN_SIM_TESTBENCH_CAT("
|
803
|
+
strcpy(comment, ORIGEN_SIM_TESTBENCH_CAT(ORIGEN_SIM_DEBUG_MODULE_CAT("comments")));
|
790
804
|
strcat(comment, arg1);
|
791
805
|
|
792
806
|
handle = vpi_handle_by_name(comment, NULL);
|
@@ -989,7 +1003,7 @@ static void end_simulation() {
|
|
989
1003
|
s_vpi_value v;
|
990
1004
|
|
991
1005
|
// Setting this node will cause the testbench to call $finish
|
992
|
-
handle = vpi_handle_by_name(ORIGEN_SIM_TESTBENCH_CAT(
|
1006
|
+
handle = vpi_handle_by_name(ORIGEN_SIM_TESTBENCH_CAT(ORIGEN_FINISH_SIG_NAME), NULL);
|
993
1007
|
v.format = vpiDecStrVal;
|
994
1008
|
v.value.str = "1";
|
995
1009
|
vpi_put_value(handle, &v, NULL, vpiNoDelay);
|
@@ -1057,7 +1071,7 @@ PLI_INT32 bridge_on_miscompare(PLI_BYTE8 * user_dat) {
|
|
1057
1071
|
if (match_loop_open) {
|
1058
1072
|
match_loop_error_count++;
|
1059
1073
|
|
1060
|
-
handle = vpi_handle_by_name(ORIGEN_SIM_TESTBENCH_CAT("
|
1074
|
+
handle = vpi_handle_by_name(ORIGEN_SIM_TESTBENCH_CAT(ORIGEN_SIM_DEBUG_MODULE_CAT("match_errors")), NULL);
|
1061
1075
|
val.format = vpiIntVal;
|
1062
1076
|
val.value.integer = match_loop_error_count;
|
1063
1077
|
vpi_put_value(handle, &val, NULL, vpiNoDelay);
|
@@ -1094,7 +1108,7 @@ PLI_INT32 bridge_on_miscompare(PLI_BYTE8 * user_dat) {
|
|
1094
1108
|
|
1095
1109
|
error_count++;
|
1096
1110
|
|
1097
|
-
handle = vpi_handle_by_name(ORIGEN_SIM_TESTBENCH_CAT("
|
1111
|
+
handle = vpi_handle_by_name(ORIGEN_SIM_TESTBENCH_CAT(ORIGEN_SIM_DEBUG_MODULE_CAT("errors")), NULL);
|
1098
1112
|
val.format = vpiIntVal;
|
1099
1113
|
val.value.integer = error_count;
|
1100
1114
|
vpi_put_value(handle, &val, NULL, vpiNoDelay);
|
data/ext/common.h
CHANGED
@@ -14,6 +14,7 @@
|
|
14
14
|
/// Prepends the testbench name to the signal.
|
15
15
|
/// e.g.: TESTBENCH_CAT(pins) => TESTBENCH_NAME.pins => origen.pins
|
16
16
|
#define ORIGEN_SIM_TESTBENCH_CAT(signal) ORIGEN_SIM_TESTBENCH_NAME "." signal
|
17
|
+
#define ORIGEN_SIM_DEBUG_MODULE_CAT(signal) ORIGEN_SIM_DEBUG_MODULE_NAME "." signal
|
17
18
|
|
18
19
|
#ifdef ENABLE_DEBUG
|
19
20
|
/* #define DEBUG(fmt, args...) fprintf(stderr, "DEBUG: %s:%d:%s(): " fmt, \
|
data/ext/defines.h.erb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
#ifndef DEFINES_H
|
2
2
|
#define DEFINES_H
|
3
3
|
|
4
|
+
#define ORIGEN_FINISH_SIG_NAME "<%= options[:finish_signal] %>"
|
4
5
|
#define ORIGEN_SIM_VERSION "<%= OrigenSim::VERSION %>"
|
5
6
|
#define ORIGEN_SIM_TESTBENCH_NAME "<%= options[:testbench_name] %>"
|
7
|
+
#define ORIGEN_SIM_DEBUG_MODULE_NAME "<%= options[:debug_module_name] %>"
|
8
|
+
#define ORIGEN_SIM_TB_NAME_LEN <%= options[:testbench_name].size %>
|
6
9
|
#define LOG_DEBUG 0
|
7
10
|
#define LOG_INFO 1
|
8
11
|
#define LOG_WARN 2
|
@@ -3,7 +3,22 @@ require 'origen_sim'
|
|
3
3
|
require_relative '../../../config/version'
|
4
4
|
require 'origen_verilog'
|
5
5
|
|
6
|
-
options = {
|
6
|
+
options = {
|
7
|
+
incl_files: [],
|
8
|
+
source_dirs: [],
|
9
|
+
testbench_name: 'origen',
|
10
|
+
defines: [],
|
11
|
+
user_details: {},
|
12
|
+
initial_pin_states: {},
|
13
|
+
forced_pin_types: {},
|
14
|
+
verilog_top_output_name: 'origen',
|
15
|
+
file_type: :v,
|
16
|
+
power_pins: [],
|
17
|
+
ground_pins: [],
|
18
|
+
virtual_pins: [],
|
19
|
+
other_pins: [],
|
20
|
+
passthrough: []
|
21
|
+
}
|
7
22
|
|
8
23
|
# App options are options that the application can supply to extend this command
|
9
24
|
app_options = @application_options || []
|
@@ -22,8 +37,9 @@ Usage: origen sim:build TOP_LEVEL_VERILOG_FILE [options]
|
|
22
37
|
opts.on('-s', '--source_dir PATH', 'Directories to look for include files in (the directory containing the top-level is already considered)') do |path|
|
23
38
|
options[:source_dirs] << path
|
24
39
|
end
|
25
|
-
opts.on('--sv', 'Generate a .sv file instead of a .v file.') { |t| options[:sv] = t }
|
40
|
+
opts.on('--sv', 'Generate a .sv file instead of a .v file.') { |t| options[:sv] = t; options[:file_type] = :sv }
|
26
41
|
opts.on('--wreal', 'Enable real number modeling support on DUT pins defined as real wires (wreal)') { |t| options[:wreal] = t }
|
42
|
+
opts.on('--wrealavg', 'Enable real number modeling support on DUT pins defined as real wires - averaged (wrealavg)') { |t| options[:wrealavg] = t }
|
27
43
|
opts.on('--verilog_top_output_name NAME', 'Renames the output filename from origen.v to NAME.v') do |name|
|
28
44
|
options[:verilog_top_output_name] = name
|
29
45
|
end
|
@@ -39,7 +55,25 @@ Usage: origen sim:build TOP_LEVEL_VERILOG_FILE [options]
|
|
39
55
|
end
|
40
56
|
(options[:initial_pin_states])[name.to_sym] = OrigenSim::INIT_PIN_STATE_MAPPING[state]
|
41
57
|
end
|
42
|
-
opts.on('--
|
58
|
+
opts.on('--force_pin_type PIN_AND_TYPE', 'Overwrite the pin driver discerned from DUT module') do |pin_and_type|
|
59
|
+
name, type = pin_and_type.split(':')
|
60
|
+
(options[:forced_pin_types])[name] = OrigenSim::FORCE_PIN_TYPES_MAPPING[type]
|
61
|
+
end
|
62
|
+
opts.on('--power_pins PINS_AND_REGEXES', 'Using pin names or regexes, indicate which pins are power pins, seperated by tildas') do |str_or_regex|
|
63
|
+
options[:power_pins] << str_or_regex
|
64
|
+
end
|
65
|
+
opts.on('--ground_pins PINS_AND_REGEXES', 'Using pin names or regexes, indicate which pins are ground pins, seperated by tildas') do |str_or_regex|
|
66
|
+
options[:ground_pins] << str_or_regex
|
67
|
+
end
|
68
|
+
opts.on('--virtual_pins PINS_AND_REGEXES', 'Using pin names or regexes, indicate which pins are virtual pins, seperated by tildas') do |str_or_regex|
|
69
|
+
options[:virtual_pins] << str_or_regex
|
70
|
+
end
|
71
|
+
opts.on('--other_pins PINS_AND_REGEXES', 'Using pin names or regexes, indicate which pins are \'other\' pins, seperated by tildas') do |str_or_regex|
|
72
|
+
options[:other_pins] << str_or_regex
|
73
|
+
end
|
74
|
+
opts.on('--include FILE', 'Specify files to include in the top verilog file.') { |f| options[:incl_files] << f }
|
75
|
+
opts.on('--vendor VENDOR', 'Specify the target vendor (Cadence, Synopsis, Icarus') { |v| options[:vendor] = v.downcase.to_sym }
|
76
|
+
opts.on('--passthrough SWITCHES', 'Raw switches that will be ignored by OrigenSim, but appear in the final build command') { |s| options[:passthrough] << s }
|
43
77
|
|
44
78
|
# Specifying snapshot details
|
45
79
|
opts.on('--device_name NAME', '(Snapshot Detail) Specify a device name') { |n| options[:device_name] = n }
|
@@ -48,6 +82,9 @@ Usage: origen sim:build TOP_LEVEL_VERILOG_FILE [options]
|
|
48
82
|
opts.on('--revision_note REV_NOTE', '(Snapshot Detail) Specify a brief note on this revision of the snapshot') { |n| options[:revision_note] = n }
|
49
83
|
opts.on('--author AUTHOR', '(Snapshot Detail) Specify the author of the snapshot (default is just Origen.current_user)') { |a| options[:author] = a }
|
50
84
|
|
85
|
+
opts.on('--finish_signal FINISH_SIGNAL', 'Specify the finish signal') { |f| options[:finish_signal] = f }
|
86
|
+
opts.on('--debug_module_name MOD_NAME', 'Specify the debug module name') { |d| options[:debug_module_name] = d }
|
87
|
+
|
51
88
|
# User-defined snapshot details
|
52
89
|
opts.on('--USER_DETAIL NAME_AND_VALUE', 'Specify custom user-defined details to build into the snapshot details. Format as NAME:VALUE, e.g.: \'--USER_DETAIL BUILD_TYPE:RTL\'') do |name_and_value|
|
53
90
|
name, value = name_and_value.split(':')
|
@@ -68,8 +105,41 @@ Usage: origen sim:build TOP_LEVEL_VERILOG_FILE [options]
|
|
68
105
|
opts.on('-h', '--help', 'Show this message') { puts opts; exit 0 }
|
69
106
|
end
|
70
107
|
|
108
|
+
build_cmd = 'origen sim:build ' + ARGV.map do |arg|
|
109
|
+
# Command-line-ify some of the argument values.
|
110
|
+
if arg.include?(' ') || (arg[0] == '/' && arg[1] == '/' && arg.size > 1)
|
111
|
+
# if the argument is a string, wrap it in quotes.
|
112
|
+
# Likewise, if the argument looks like a regex, wrap it in quotes as well.
|
113
|
+
arg = "\"#{arg}\""
|
114
|
+
end
|
115
|
+
|
116
|
+
# If the argument includes any !s, escape them
|
117
|
+
arg = arg.gsub('!', '\!')
|
118
|
+
|
119
|
+
arg
|
120
|
+
end.join(' ')
|
71
121
|
opt_parser.parse! ARGV
|
72
122
|
|
123
|
+
options.select { |k, v| [:power_pins, :ground_pins, :virtual_pins, :other_pins].include?(k) }.each do |k, pins_or_regexes|
|
124
|
+
options[k] = pins_or_regexes.map { |input| input.split('~') }.flatten.map do |p|
|
125
|
+
if p.start_with?('/') && p.end_with?('/')
|
126
|
+
Regexp.new(p[1..-2])
|
127
|
+
else
|
128
|
+
p
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
options[:forced_pin_types] = options[:forced_pin_types].map do |pin_or_regex, type|
|
134
|
+
if pin_or_regex.start_with?('/') && pin_or_regex.end_with?('/')
|
135
|
+
# run this as a regex, not as a single pin name
|
136
|
+
# Cut out the leading / and trailing / characters though
|
137
|
+
[Regexp.new(pin_or_regex.to_s[1..-2]), type]
|
138
|
+
else
|
139
|
+
[pin_or_regex, type]
|
140
|
+
end
|
141
|
+
end.to_h
|
142
|
+
|
73
143
|
def _exit_fail_
|
74
144
|
if $_testing_build_return_dut_
|
75
145
|
return nil
|
@@ -115,7 +185,7 @@ end
|
|
115
185
|
|
116
186
|
rtl_top_module = mod.name
|
117
187
|
|
118
|
-
mod.to_top_level # Creates dut
|
188
|
+
mod.to_top_level(options) # Creates dut
|
119
189
|
|
120
190
|
# Update the pins with any settings from the command line
|
121
191
|
options[:initial_pin_states].each do |pin, state|
|
@@ -138,15 +208,22 @@ else
|
|
138
208
|
quiet: true,
|
139
209
|
preserve_target: true,
|
140
210
|
options: {
|
141
|
-
vendor: :
|
211
|
+
vendor: options[:vendor],
|
142
212
|
top: dut.name,
|
213
|
+
testbench_name: options[:testbench_name],
|
143
214
|
incl: options[:incl_files],
|
144
215
|
device_name: options[:device_name],
|
145
216
|
revision: options[:revision],
|
146
217
|
revision_note: options[:revision_note],
|
147
218
|
parent_tb_version: options[:testbench_version],
|
148
219
|
user_details: options[:user_details],
|
149
|
-
author: options[:author]
|
220
|
+
author: options[:author],
|
221
|
+
build_cmd: build_cmd,
|
222
|
+
file_type: options[:file_type],
|
223
|
+
testbench: options[:testbench_name] || 'origen',
|
224
|
+
top_level_name: options[:top_level_name] || 'dut',
|
225
|
+
finish_signal: options[:finish_signal] || 'finish',
|
226
|
+
debug_module_name: options[:debug_module_name] || 'debug'
|
150
227
|
}
|
151
228
|
|
152
229
|
Origen.app.runner.launch action: :compile,
|
@@ -182,6 +259,16 @@ else
|
|
182
259
|
)
|
183
260
|
end
|
184
261
|
|
262
|
+
if options[:wrealavg]
|
263
|
+
SYNOPSYS_SWITCHES += %w(
|
264
|
+
+define+ORIGEN_WREALAVG
|
265
|
+
-realport
|
266
|
+
-sverilog
|
267
|
+
-lca
|
268
|
+
-xlrm\ coerce_nettype
|
269
|
+
)
|
270
|
+
end
|
271
|
+
|
185
272
|
SYNOPSYS_DVE_SWITCHES = SYNOPSYS_SWITCHES + %w(
|
186
273
|
+define+ORIGEN_VPD
|
187
274
|
)
|
@@ -211,96 +298,108 @@ else
|
|
211
298
|
)
|
212
299
|
end
|
213
300
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
puts '-----------------------------------------------------------'
|
219
|
-
puts
|
220
|
-
puts 'Compile the VPI extension using the following command:'
|
221
|
-
puts
|
222
|
-
puts " cd #{output_directory} && #{ENV['ORIGEN_SIM_IVERILOG_VPI'] || 'iverilog-vpi'} *.c --name=origen && cd #{Pathname.pwd}"
|
223
|
-
puts
|
224
|
-
puts 'Add the following to your build script (AND REMOVE ANY OTHER TESTBENCH!):'
|
225
|
-
puts
|
226
|
-
puts " #{output_directory}/#{output_name} \\"
|
227
|
-
puts ' -o origen.vvp \\'
|
228
|
-
puts ' -DORIGEN_VCD'
|
229
|
-
puts
|
230
|
-
puts 'Here is an example which may work for the file you just parsed (add additional source dirs with more -I options at the end if required):'
|
231
|
-
puts
|
232
|
-
puts " #{ENV['ORIGEN_SIM_IVERILOG'] || 'iverilog'} #{rtl_top} #{output_directory}/#{output_name} -o origen.vvp -DORIGEN_VCD -I #{Pathname.new(rtl_top).dirname}"
|
233
|
-
puts
|
234
|
-
puts 'Copy the following files (produced by iverilog) to simulation/<target>/icarus/. within your Origen application:'
|
235
|
-
puts
|
236
|
-
puts " #{output_directory}/origen.vpi"
|
237
|
-
puts ' origen.vvp'
|
238
|
-
puts
|
239
|
-
puts '-----------------------------------------------------------'
|
240
|
-
puts 'Synopsys VCS w/ DVE Waveviewer'
|
241
|
-
puts '-----------------------------------------------------------'
|
242
|
-
puts
|
243
|
-
puts 'Add the following to your build script (AND REMOVE ANY OTHER TESTBENCH!):'
|
244
|
-
puts
|
245
|
-
SYNOPSYS_DVE_SWITCHES.each do |switch|
|
246
|
-
puts " #{switch} \\"
|
301
|
+
if options[:wrealavg]
|
302
|
+
CADENCE_SWITCHES += %w(
|
303
|
+
+define+ORIGEN_WREALAVG
|
304
|
+
)
|
247
305
|
end
|
306
|
+
|
248
307
|
puts
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
puts
|
308
|
+
if options[:vendor].nil? || options[:vendor] == :icarus
|
309
|
+
puts
|
310
|
+
puts '-----------------------------------------------------------'
|
311
|
+
puts 'Icarus Verilog'
|
312
|
+
puts '-----------------------------------------------------------'
|
313
|
+
puts
|
314
|
+
puts 'Compile the VPI extension using the following command:'
|
315
|
+
puts
|
316
|
+
puts " cd #{output_directory} && #{ENV['ORIGEN_SIM_IVERILOG_VPI'] || 'iverilog-vpi'} *.c --name=origen && cd #{Pathname.pwd}"
|
317
|
+
puts
|
318
|
+
puts 'Add the following to your build script (AND REMOVE ANY OTHER TESTBENCH!):'
|
319
|
+
puts
|
320
|
+
puts " #{output_directory}/#{output_name} \\"
|
321
|
+
puts ' -o origen.vvp \\'
|
322
|
+
puts ' -DORIGEN_VCD'
|
323
|
+
puts
|
324
|
+
puts 'Here is an example which may work for the file you just parsed (add additional source dirs with more -I options at the end if required):'
|
325
|
+
puts
|
326
|
+
puts " #{ENV['ORIGEN_SIM_IVERILOG'] || 'iverilog'} #{rtl_top} #{output_directory}/#{output_name} -o origen.vvp -DORIGEN_VCD -I #{Pathname.new(rtl_top).dirname}"
|
327
|
+
puts
|
328
|
+
puts 'Copy the following files (produced by iverilog) to simulation/<target>/icarus/. within your Origen application:'
|
329
|
+
puts
|
330
|
+
puts " #{output_directory}/origen.vpi"
|
331
|
+
puts ' origen.vvp'
|
266
332
|
end
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
puts
|
333
|
+
if options[:vendor].nil? || options[:vendor] == :synopsis
|
334
|
+
puts
|
335
|
+
puts '-----------------------------------------------------------'
|
336
|
+
puts 'Synopsys VCS w/ DVE Waveviewer'
|
337
|
+
puts '-----------------------------------------------------------'
|
338
|
+
puts
|
339
|
+
puts 'Add the following to your build script (AND REMOVE ANY OTHER TESTBENCH!):'
|
340
|
+
puts
|
341
|
+
SYNOPSYS_DVE_SWITCHES.each do |switch|
|
342
|
+
puts " #{switch} \\"
|
343
|
+
end
|
344
|
+
puts
|
345
|
+
puts 'Here is an example which may work for the file you just parsed (add additional +incdir+ options at the end if required):'
|
346
|
+
puts
|
347
|
+
puts " #{ENV['ORIGEN_SIM_VCS'] || 'vcs'} #{rtl_top} +incdir+#{Pathname.new(rtl_top).dirname} " + SYNOPSYS_DVE_SWITCHES.join(' ') + (options[:passthrough] ? " #{options[:passthrough].join(' ')}" : '')
|
348
|
+
puts
|
349
|
+
puts 'Copy the following files (produced by vcs) to simulation/<target>/synopsys/. within your Origen application:'
|
350
|
+
puts
|
351
|
+
puts ' simv'
|
352
|
+
puts ' simv.daidir'
|
353
|
+
puts
|
354
|
+
puts '-----------------------------------------------------------'
|
355
|
+
puts 'Synopsys VCS w/ Verdi Waveviewer'
|
356
|
+
puts '-----------------------------------------------------------'
|
357
|
+
puts
|
358
|
+
puts 'Add the following to your build script (AND REMOVE ANY OTHER TESTBENCH!):'
|
359
|
+
puts
|
360
|
+
SYNOPSYS_VERDI_SWITCHES.each do |switch|
|
361
|
+
puts " #{switch} \\"
|
362
|
+
end
|
363
|
+
puts
|
364
|
+
puts 'Here is an example which may work for the file you just parsed (add additional +incdir+ options at the end if required):'
|
365
|
+
puts
|
366
|
+
puts " #{ENV['ORIGEN_SIM_VCS'] || 'vcs'} #{rtl_top} +incdir+#{Pathname.new(rtl_top).dirname} " + SYNOPSYS_VERDI_SWITCHES.join(' ') + (options[:passthrough] ? " #{options[:passthrough].join(' ')}" : '')
|
367
|
+
puts
|
368
|
+
puts 'Copy the following files (produced by vcs) to simulation/<target>/synopsys/. within your Origen application:'
|
369
|
+
puts
|
370
|
+
puts ' simv'
|
371
|
+
puts ' simv.daidir'
|
372
|
+
puts
|
373
|
+
puts '-----------------------------------------------------------'
|
374
|
+
puts 'Cadence Incisive (irun)'
|
375
|
+
puts '-----------------------------------------------------------'
|
376
|
+
puts
|
377
|
+
puts 'Add the following to your build script (AND REMOVE ANY OTHER TESTBENCH!):'
|
378
|
+
end
|
379
|
+
if options[:vendor].nil? || options[:vendor] == :cadence
|
380
|
+
puts
|
381
|
+
CADENCE_SWITCHES.each do |switch|
|
382
|
+
puts " #{switch} \\"
|
383
|
+
end
|
384
|
+
puts
|
385
|
+
puts 'Here is an example which may work for the file you just parsed (add additional -incdir options at the end if required):'
|
386
|
+
puts
|
387
|
+
puts " #{ENV['ORIGEN_SIM_IRUN'] || 'irun'} #{rtl_top} -incdir #{Pathname.new(rtl_top).dirname} " + CADENCE_SWITCHES.join(' ') + (options[:passthrough] ? " #{options[:passthrough].join(' ')}" : '')
|
388
|
+
puts
|
389
|
+
puts 'Copy the following directory (produced by irun) to simulation/<target>/cadence/. within your Origen application:'
|
390
|
+
puts
|
391
|
+
puts ' INCA_libs'
|
392
|
+
puts
|
393
|
+
puts '-----------------------------------------------------------'
|
394
|
+
puts
|
395
|
+
puts 'Testbench and VPI extension created!'
|
396
|
+
puts
|
397
|
+
puts 'This file can be imported into an Origen top-level DUT model to define the pins:'
|
398
|
+
puts
|
399
|
+
puts " #{output_directory}/#{rtl_top_module}.rb"
|
400
|
+
puts
|
401
|
+
puts 'See above for what to do now to create an Origen-enabled simulation object for your particular simulator.'
|
285
402
|
end
|
286
|
-
puts
|
287
|
-
puts 'Here is an example which may work for the file you just parsed (add additional -incdir options at the end if required):'
|
288
|
-
puts
|
289
|
-
puts " #{ENV['ORIGEN_SIM_IRUN'] || 'irun'} #{rtl_top} -incdir #{Pathname.new(rtl_top).dirname} " + CADENCE_SWITCHES.join(' ')
|
290
|
-
puts
|
291
|
-
puts 'Copy the following directory (produced by irun) to simulation/<target>/cadence/. within your Origen application:'
|
292
|
-
puts
|
293
|
-
puts ' INCA_libs'
|
294
|
-
puts
|
295
|
-
puts '-----------------------------------------------------------'
|
296
|
-
puts
|
297
|
-
puts 'Testbench and VPI extension created!'
|
298
|
-
puts
|
299
|
-
puts 'This file can be imported into an Origen top-level DUT model to define the pins:'
|
300
|
-
puts
|
301
|
-
puts " #{output_directory}/#{rtl_top_module}.rb"
|
302
|
-
puts
|
303
|
-
puts 'See above for what to do now to create an Origen-enabled simulation object for your particular simulator.'
|
304
403
|
puts
|
305
404
|
|
306
405
|
end
|
@@ -57,7 +57,7 @@ module Origen
|
|
57
57
|
|
58
58
|
alias_method :_orig_drive, :drive
|
59
59
|
def drive(*args)
|
60
|
-
if _analog_pin_? && simulation_running? && tester.simulator.
|
60
|
+
if _analog_pin_? && simulation_running? && tester.simulator.real?
|
61
61
|
tester.poke("#{driver_net}.drive_en", 1)
|
62
62
|
tester.poke("#{driver_net}.drive", args.first + 0.0)
|
63
63
|
else
|
@@ -68,11 +68,11 @@ module Origen
|
|
68
68
|
|
69
69
|
alias_method :_orig_assert, :assert
|
70
70
|
def assert(*args)
|
71
|
-
if _analog_pin_? && simulation_running? && tester.simulator.
|
71
|
+
if _analog_pin_? && simulation_running? && tester.simulator.real?
|
72
72
|
drive_enabled = tester.peek("#{driver_net}.drive_en").to_i
|
73
73
|
if drive_enabled == 1
|
74
|
-
tester.poke("#{driver_net}.drive_en", 0)
|
75
|
-
tester.cycle
|
74
|
+
# tester.poke("#{driver_net}.drive_en", 0)
|
75
|
+
# tester.cycle
|
76
76
|
end
|
77
77
|
measured = tester.peek("#{driver_net}.pin", true)
|
78
78
|
# Could implement checking/limits here in future
|