Task 166: .EBD File Format
Task 166: .EBD File Format
- The .EBD file format is the Electrical Board Description format as defined in the IBIS specification. The intrinsic properties of this file format include:
- IBIS Version: The version of the IBIS specification used.
- File Name: The name of the .EBD file.
- File Revision: The revision number of the file.
- Date: The date of file creation or modification.
- Source: The source of the data or model.
- Notes: Additional notes about the file or model.
- Disclaimer: Any disclaimers regarding the use of the model.
- Copyright: Copyright information.
- Begin Board Description: Marker for the start of the board description section.
- Manufacturer: The name of the manufacturer.
- OEM: The original equipment manufacturer, if applicable.
- Description: A description of the board or module.
- Number of Pins: The total number of pins on the board.
- Number of Pin Columns: The number of columns in the pin list (typically 2: pin and signal_name).
- Pin List: A list of pins with associated signal names.
- Path Description: Detailed electrical path descriptions for each pin, including lengths (Len), inductance (L), capacitance (C), resistance (R), forks, endforks, and nodes referencing components and pins.
- Reference Designator Map: Mapping of reference designators to corresponding .ibs files and component names.
- End Board Description: Marker for the end of the board description section.
- End: Marker for the end of the file.
Two direct download links for .EBD files could not be located in publicly available sources. The IBIS specification and related documents provide examples of .EBD content, but no direct downloads of .EBD files were identified.
The following is an HTML with embedded JavaScript for a simple web page (suitable for embedding in a Ghost blog or similar) that allows drag-and-drop of a .EBD file and dumps all the properties to the screen:
Drag and drop .EBD file here
- The following is a Python class for handling .EBD files:
class EBDHandler:
def __init__(self):
self.properties = {}
self.pin_list = []
self.path_descriptions = {}
self.ref_map = []
self.current_section = None
def open_and_decode(self, filepath):
with open(filepath, 'r') as f:
content = f.read()
lines = content.split('\n')
for line in lines:
line = line.strip()
if line.startswith('[') and line.endswith(']'):
self.current_section = line[1:-1].strip()
self.properties[self.current_section] = ''
elif self.current_section:
if self.current_section == 'Path Description':
if line.startswith('Pin'):
pin = line.split()[1]
self.path_descriptions[pin] = []
elif line:
self.path_descriptions[list(self.path_descriptions.keys())[-1]].append(line)
elif self.current_section == 'Pin List':
if line and not line.startswith('|'):
self.pin_list.append(line)
elif self.current_section == 'Reference Designator Map':
if line and not line.startswith('|'):
self.ref_map.append(line)
else:
self.properties[self.current_section] += line + '\n'
self.properties['Pin List'] = self.pin_list
self.properties['Path Descriptions'] = self.path_descriptions
self.properties['Reference Designator Map'] = self.ref_map
def print_properties(self):
import json
print(json.dumps(self.properties, indent=4))
def write(self, filepath):
with open(filepath, 'w') as f:
for key, value in self.properties.items():
if key in ['Pin List', 'Path Descriptions', 'Reference Designator Map']:
f.write(f'[{key}]\n')
if key == 'Pin List':
for item in value:
f.write(item + '\n')
elif key == 'Path Descriptions':
for pin, desc in value.items():
f.write(f'Pin {pin}\n')
for line in desc:
f.write(line + '\n')
elif key == 'Reference Designator Map':
for item in value:
f.write(item + '\n')
else:
f.write(f'[{key}] {value.strip()}\n')
f.write('[End]\n')
# Example usage:
# handler = EBDHandler()
# handler.open_and_decode('example.ebd')
# handler.print_properties()
# handler.write('output.ebd')
- The following is a Java class for handling .EBD files:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
public class EBDHandler {
private Map<String, Object> properties = new LinkedHashMap<>();
private ArrayList<String> pinList = new ArrayList<>();
private Map<String, ArrayList<String>> pathDescriptions = new LinkedHashMap<>();
private ArrayList<String> refMap = new ArrayList<>();
private String currentSection = null;
public void openAndDecode(String filepath) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(filepath))) {
String line;
while (line != null) {
line = reader.readLine();
if (line == null) break;
line = line.trim();
if (line.startsWith("[") && line.endsWith("]")) {
currentSection = line.substring(1, line.length() - 1).trim();
properties.put(currentSection, "");
} else if (currentSection != null) {
if (currentSection.equals("Path Description")) {
if (line.startsWith("Pin")) {
String pin = line.split("\\s+")[1];
pathDescriptions.put(pin, new ArrayList<>());
} else if (!line.isEmpty()) {
pathDescriptions.get(pathDescriptions.keySet().toArray()[pathDescriptions.size() - 1]).add(line);
}
} else if (currentSection.equals("Pin List")) {
if (!line.isEmpty() && !line.startsWith("|")) {
pinList.add(line);
}
} else if (currentSection.equals("Reference Designator Map")) {
if (!line.isEmpty() && !line.startsWith("|")) {
refMap.add(line);
}
} else {
properties.put(currentSection, (String) properties.get(currentSection) + line + "\n");
}
}
}
}
properties.put("Pin List", pinList);
properties.put("Path Descriptions", pathDescriptions);
properties.put("Reference Designator Map", refMap);
}
public void printProperties() {
System.out.println(new com.google.gson.GsonBuilder().setPrettyPrinting().create().toJson(properties));
}
public void write(String filepath) throws IOException {
try (FileWriter writer = new FileWriter(filepath)) {
for (Map.Entry<String, Object> entry : properties.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (key.equals("Pin List")) {
writer.write("[" + key + "]\n");
((ArrayList<String>) value).forEach(item -> {
try {
writer.write(item + "\n");
} catch (IOException e) {
e.printStackTrace();
}
});
} else if (key.equals("Path Descriptions")) {
writer.write("[" + key + "]\n");
((Map<String, ArrayList<String>>) value).forEach((pin, desc) -> {
try {
writer.write("Pin " + pin + "\n");
desc.forEach(line -> {
try {
writer.write(line + "\n");
} catch (IOException e) {
e.printStackTrace();
}
});
} catch (IOException e) {
e.printStackTrace();
}
});
} else if (key.equals("Reference Designator Map")) {
writer.write("[" + key + "]\n");
((ArrayList<String>) value).forEach(item -> {
try {
writer.write(item + "\n");
} catch (IOException e) {
e.printStackTrace();
}
});
} else {
writer.write("[" + key + "] " + ((String) value).trim() + "\n");
}
}
writer.write("[End]\n");
}
}
// Example usage:
// public static void main(String[] args) throws IOException {
// EBDHandler handler = new EBDHandler();
// handler.openAndDecode("example.ebd");
// handler.printProperties();
// handler.write("output.ebd");
// }
}
- The following is a JavaScript class for handling .EBD files (node.js environment, using fs module):
const fs = require('fs');
class EBDHandler {
constructor() {
this.properties = {};
this.pinList = [];
this.pathDescriptions = {};
this.refMap = [];
this.currentSection = null;
}
openAndDecode(filepath) {
const content = fs.readFileSync(filepath, 'utf8');
const lines = content.split('\n');
lines.forEach((line) => {
line = line.trim();
if (line.startsWith('[') && line.endsWith(']')) {
this.currentSection = line.slice(1, -1).trim();
this.properties[this.currentSection] = '';
} else if (this.currentSection) {
if (this.currentSection === 'Path Description') {
if (line.startsWith('Pin')) {
const pin = line.split(/\s+/)[1];
this.pathDescriptions[pin] = [];
} else if (line) {
this.pathDescriptions[Object.keys(this.pathDescriptions)[Object.keys(this.pathDescriptions).length - 1]].push(line);
}
} else if (this.currentSection === 'Pin List') {
if (line && !line.startsWith('|')) {
this.pinList.push(line);
}
} else if (this.currentSection === 'Reference Designator Map') {
if (line && !line.startsWith('|')) {
this.refMap.push(line);
}
} else {
this.properties[this.currentSection] += line + '\n';
}
}
});
this.properties['Pin List'] = this.pinList;
this.properties['Path Descriptions'] = this.pathDescriptions;
this.properties['Reference Designator Map'] = this.refMap;
}
printProperties() {
console.log(JSON.stringify(this.properties, null, 2));
}
write(filepath) {
let output = '';
for (const [key, value] of Object.entries(this.properties)) {
if (key === 'Pin List') {
output += `[${key}]\n`;
value.forEach(item => output += item + '\n');
} else if (key === 'Path Descriptions') {
output += `[${key}]\n`;
for (const [pin, desc] of Object.entries(value)) {
output += `Pin ${pin}\n`;
desc.forEach(line => output += line + '\n');
}
} else if (key === 'Reference Designator Map') {
output += `[${key}]\n`;
value.forEach(item => output += item + '\n');
} else {
output += `[${key}] ${value.trim()}\n`;
}
}
output += '[End]\n';
fs.writeFileSync(filepath, output);
}
}
// Example usage:
// const handler = new EBDHandler();
// handler.openAndDecode('example.ebd');
// handler.printProperties();
// handler.write('output.ebd');
- The following is a C class (using struct for properties) for handling .EBD files:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE 256
#define MAX_SECTIONS 20
#define MAX_PINS 1000
typedef struct {
char *key;
char *value;
} KeyValue;
typedef struct {
KeyValue sections[MAX_SECTIONS];
int section_count;
char *pin_list[MAX_PINS];
int pin_count;
// For path descriptions, use a simple string map simulation
char *path_keys[MAX_PINS];
char *path_values[MAX_PINS];
int path_count;
char *ref_map[MAX_PINS];
int ref_count;
} EBDProperties;
void init_EBDProperties(EBDProperties *props) {
props->section_count = 0;
props->pin_count = 0;
props->path_count = 0;
props->ref_count = 0;
}
void open_and_decode(EBDProperties *props, const char *filepath) {
FILE *fp = fopen(filepath, "r");
if (!fp) return;
char line[MAX_LINE];
char *current_section = NULL;
char *current_path_pin = NULL;
while (fgets(line, MAX_LINE, fp)) {
line[strcspn(line, "\n")] = 0; // Trim newline
char *trimmed = line;
while (*trimmed == ' ') trimmed++;
if (trimmed[0] == '[' && trimmed[strlen(trimmed)-1] == ']') {
free(current_section);
current_section = strdup(trimmed + 1);
current_section[strlen(current_section)-1] = 0;
props->sections[props->section_count].key = strdup(current_section);
props->sections[props->section_count].value = strdup("");
props->section_count++;
} else if (current_section) {
if (strcmp(current_section, "Path Description") == 0) {
if (strncmp(trimmed, "Pin", 3) == 0) {
char *pin = trimmed + 4;
props->path_keys[props->path_count] = strdup(pin);
props->path_values[props->path_count] = strdup("");
current_path_pin = props->path_keys[props->path_count];
props->path_count++;
} else if (strlen(trimmed) > 0) {
char *new_val = malloc(strlen(props->path_values[props->path_count-1]) + strlen(trimmed) + 2);
sprintf(new_val, "%s%s\n", props->path_values[props->path_count-1], trimmed);
free(props->path_values[props->path_count-1]);
props->path_values[props->path_count-1] = new_val;
}
} else if (strcmp(current_section, "Pin List") == 0) {
if (strlen(trimmed) > 0 && trimmed[0] != '|') {
props->pin_list[props->pin_count++] = strdup(trimmed);
}
} else if (strcmp(current_section, "Reference Designator Map") == 0) {
if (strlen(trimmed) > 0 && trimmed[0] != '|') {
props->ref_map[props->ref_count++] = strdup(trimmed);
}
} else {
char *new_val = malloc(strlen(props->sections[props->section_count-1].value) + strlen(trimmed) + 2);
sprintf(new_val, "%s%s\n", props->sections[props->section_count-1].value, trimmed);
free(props->sections[props->section_count-1].value);
props->sections[props->section_count-1].value = new_val;
}
}
}
fclose(fp);
free(current_section);
}
void print_properties(EBDProperties *props) {
for (int i = 0; i < props->section_count; i++) {
printf("[%s] %s\n", props->sections[i].key, props->sections[i].value);
}
printf("[Pin List]\n");
for (int i = 0; i < props->pin_count; i++) {
printf("%s\n", props->pin_list[i]);
}
printf("[Path Descriptions]\n");
for (int i = 0; i < props->path_count; i++) {
printf("Pin %s\n%s", props->path_keys[i], props->path_values[i]);
}
printf("[Reference Designator Map]\n");
for (int i = 0; i < props->ref_count; i++) {
printf("%s\n", props->ref_map[i]);
}
}
void write(EBDProperties *props, const char *filepath) {
FILE *fp = fopen(filepath, "w");
if (!fp) return;
for (int i = 0; i < props->section_count; i++) {
fprintf(fp, "[%s] %s\n", props->sections[i].key, props->sections[i].value);
}
fprintf(fp, "[Pin List]\n");
for (int i = 0; i < props->pin_count; i++) {
fprintf(fp, "%s\n", props->pin_list[i]);
}
fprintf(fp, "[Path Description]\n");
for (int i = 0; i < props->path_count; i++) {
fprintf(fp, "Pin %s\n%s", props->path_keys[i], props->path_values[i]);
}
fprintf(fp, "[Reference Designator Map]\n");
for (int i = 0; i < props->ref_count; i++) {
fprintf(fp, "%s\n", props->ref_map[i]);
}
fprintf(fp, "[End]\n");
fclose(fp);
}
// Example usage:
// int main() {
// EBDProperties props;
// init_EBDProperties(&props);
// open_and_decode(&props, "example.ebd");
// print_properties(&props);
// write(&props, "output.ebd");
// // Free memory...
// return 0;
// }