ext/bridge.c in origen_sim-0.11.1 vs ext/bridge.c in origen_sim-0.12.0
- old
+ new
@@ -10,13 +10,14 @@
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#define MAX_NUMBER_PINS 2000
-#define MAX_WAVE_EVENTS 10
+#define MAX_WAVE_EVENTS 50
typedef struct Pin {
+ char *name;
vpiHandle data; // A handle to the driver data register
vpiHandle drive; // A handle to the driver drive enable register
vpiHandle force_data; // A handle to the driver force_data register
vpiHandle compare; // A handle to the driver compare enable register
vpiHandle capture; // A handle to the driver capture enable register
@@ -25,10 +26,11 @@
int drive_wave_pos; // Position of the pin in the drive_wave's active pin array
int compare_wave_pos; // Position of the pin in the compare_wave's active pin array
int index; // The pin's index in the pins array
int previous_state; // Used to keep track of whether the pin was previously driving or comparing
bool capture_en; // Used to indicated when compare data should be captured instead of compared
+ bool present; // Set to true if the pin is present in the testbench
} Pin;
typedef struct Event {
uint64_t time;
char data;
@@ -74,26 +76,36 @@
static void bridge_define_pin(char * name, char * pin_ix, char * drive_wave_ix, char * compare_wave_ix) {
int index = atoi(pin_ix);
Pin *pin = &pins[index];
number_of_pins += 1;
+ (*pin).name = malloc(strlen(name) + 1);
+ strcpy((*pin).name, name);
(*pin).index = index;
(*pin).drive_wave = atoi(drive_wave_ix);
(*pin).compare_wave = atoi(compare_wave_ix);
(*pin).previous_state = 0;
(*pin).capture_en = false;
+
char * driver = (char *) malloc(strlen(name) + 16);
strcpy(driver, ORIGEN_SIM_TESTBENCH_CAT("pins."));
strcat(driver, name);
char * data = (char *) malloc(strlen(driver) + 16);
strcpy(data, driver);
strcat(data, ".data");
(*pin).data = vpi_handle_by_name(data, NULL);
free(data);
+ if (!(*pin).data) {
+ vpi_printf("WARNING: Your DUT defines pin '%s', however it is not present in the testbench and will be ignored\n", (*pin).name);
+ (*pin).present = false;
+ } else {
+ (*pin).present = true;
+ }
+
char * drive = (char *) malloc(strlen(driver) + 16);
strcpy(drive, driver);
strcat(drive, ".drive");
(*pin).drive = vpi_handle_by_name(drive, NULL);
free(drive);
@@ -252,10 +264,14 @@
(*wave).active_pin_count -= 1;
}
static void bridge_clear_waves_and_pins() {
+ for (int i = 0; i < number_of_pins; i++) {
+ Pin *pin = &pins[i];
+ free((*pin).name);
+ }
number_of_pins = 0;
number_of_drive_waves = 0;
number_of_compare_waves = 0;
}
@@ -284,60 +300,64 @@
/// Immediately drives the given pin to the given value
static void bridge_drive_pin(char * index, char * val) {
Pin *pin = &pins[atoi(index)];
s_vpi_value v = {vpiIntVal, {0}};
- // Apply the data value to the pin's driver
- v.value.integer = (val[0] - '0');
- vpi_put_value((*pin).data, &v, NULL, vpiNoDelay);
- // Make sure not comparing
- v.value.integer = 0;
- vpi_put_value((*pin).compare, &v, NULL, vpiNoDelay);
+ if ((*pin).present) {
+ // Apply the data value to the pin's driver
+ v.value.integer = (val[0] - '0');
+ vpi_put_value((*pin).data, &v, NULL, vpiNoDelay);
+ // Make sure not comparing
+ v.value.integer = 0;
+ vpi_put_value((*pin).compare, &v, NULL, vpiNoDelay);
- // Register it as actively driving with it's wave
-
- // If it is already driving the wave will already be setup
- if ((*pin).previous_state != 1) {
- // If the drive is for the whole cycle, then we can enable it here
- // and don't need a callback
- if (bridge_is_drive_whole_cycle(pin)) {
- v.value.integer = 1;
- vpi_put_value((*pin).drive, &v, NULL, vpiNoDelay);
- } else {
- bridge_enable_drive_wave(pin);
- }
+ // Register it as actively driving with it's wave
+
+ // If it is already driving the wave will already be setup
+ if ((*pin).previous_state != 1) {
+ // If the drive is for the whole cycle, then we can enable it here
+ // and don't need a callback
+ if (bridge_is_drive_whole_cycle(pin)) {
+ v.value.integer = 1;
+ vpi_put_value((*pin).drive, &v, NULL, vpiNoDelay);
+ } else {
+ bridge_enable_drive_wave(pin);
+ }
- if ((*pin).previous_state == 2) {
- bridge_disable_compare_wave(pin);
+ if ((*pin).previous_state == 2) {
+ bridge_disable_compare_wave(pin);
+ }
+ (*pin).previous_state = 1;
}
- (*pin).previous_state = 1;
}
}
/// Immediately sets the given pin to compare against the given value
static void bridge_compare_pin(char * index, char * val) {
Pin *pin = &pins[atoi(index)];
s_vpi_value v = {vpiIntVal, {0}};
- // Apply the data value to the pin's driver, don't enable compare yet,
- // the wave will do that later
- v.value.integer = (val[0] - '0');
- vpi_put_value((*pin).data, &v, NULL, vpiNoDelay);
- // Make sure not driving
- v.value.integer = 0;
- vpi_put_value((*pin).drive, &v, NULL, vpiNoDelay);
+ if ((*pin).present) {
+ // Apply the data value to the pin's driver, don't enable compare yet,
+ // the wave will do that later
+ v.value.integer = (val[0] - '0');
+ vpi_put_value((*pin).data, &v, NULL, vpiNoDelay);
+ // Make sure not driving
+ v.value.integer = 0;
+ vpi_put_value((*pin).drive, &v, NULL, vpiNoDelay);
- // Register it as actively comparing with it's wave
-
- // If it is already comparing the wave will already be setup
- if ((*pin).previous_state != 2) {
- bridge_enable_compare_wave(pin);
- if ((*pin).previous_state == 1) {
- bridge_disable_drive_wave(pin);
+ // Register it as actively comparing with it's wave
+
+ // If it is already comparing the wave will already be setup
+ if ((*pin).previous_state != 2) {
+ bridge_enable_compare_wave(pin);
+ if ((*pin).previous_state == 1) {
+ bridge_disable_drive_wave(pin);
+ }
+ (*pin).previous_state = 2;
}
- (*pin).previous_state = 2;
}
}
/// Immediately sets the given pin to capture by registering it for compare
@@ -359,24 +379,26 @@
/// Immediately sets the given pin to don't compare
static void bridge_dont_care_pin(char * index) {
Pin *pin = &pins[atoi(index)];
s_vpi_value v = {vpiIntVal, {0}};
- // Disable drive and compare on the pin's driver
- v.value.integer = 0;
- vpi_put_value((*pin).drive, &v, NULL, vpiNoDelay);
- vpi_put_value((*pin).compare, &v, NULL, vpiNoDelay);
+ if ((*pin).present) {
+ // Disable drive and compare on the pin's driver
+ v.value.integer = 0;
+ vpi_put_value((*pin).drive, &v, NULL, vpiNoDelay);
+ vpi_put_value((*pin).compare, &v, NULL, vpiNoDelay);
- if ((*pin).previous_state != 0) {
- if ((*pin).previous_state == 1) {
- if (!bridge_is_drive_whole_cycle(pin)) {
- bridge_disable_drive_wave(pin);
+ if ((*pin).previous_state != 0) {
+ if ((*pin).previous_state == 1) {
+ if (!bridge_is_drive_whole_cycle(pin)) {
+ bridge_disable_drive_wave(pin);
+ }
}
+ if ((*pin).previous_state == 2) {
+ bridge_disable_compare_wave(pin);
+ }
+ (*pin).previous_state = 0;
}
- if ((*pin).previous_state == 2) {
- bridge_disable_compare_wave(pin);
- }
- (*pin).previous_state = 0;
}
}
/// Callback handler to implement the events registered by bridge_register_wave_event