2.3. Data Model¶
Managing the storage of the collected Metrics is a challenging task. Collecting metrics from hundreds, or even thousands, of EDA flows introduces the pondering question: How should we structure the data to make efficient use of it in predictive analytics applications?
EDAAC implements a general-purpose data model in edaac.models
sub-package. Below, we document its functionality.
2.3.1. Documents¶
EDAAC’s data model is an unstructured document that represents an SoC project during its different life stages (from logic synthesis to routing).
The root of the data model is a Project
document.
A Project
is a container for all related artifacts of the design lifecycle.
Below is a complete birds-eye view of the Project
document.
Usage: from edaac.models import Project
Every embedded document in the project has a class representation in edaac.models
.
For example, the technology
key in the project should be an instance of edaac.models.Technology
.
Similarly, design
, flow
, stage
and tool
should be instances of
edaac.models.Design
, edaac.models.Flow
, edaac.models.Stage
and edaac.models.Tool
respectively.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | {
"name": "<Project Name>",
"description": "<Project Description>",
"technology": {
"foundry": "<Example: TSMC>",
"process": 65,
"beol": "<Back End Of Line>",
"tracl": "<The height of the track>",
"opv": "<Operating voltage>",
"vt": "<Voltage threshold>",
"channel_width": "<Channel width>",
"config": "<Configuration>",
"version": "<Version>",
"rag": "<Red | Amber | Green>"
},
"design": {
"name": "<Design Name>",
"rtl_files": [
"<Absolute Path of verilog RTL file>",
"<Absolute Path of verilog RTL file>"
],
"netlist_file": "<Absolute path of netlist file (after synthesis)>",
"sdc_file": "<Absolute path of constraints file (ins .sdc format)>",
"runset_tag": "<RTL related tags for the release candidates>",
"runset_id": "<ID of the release candidates>",
"rtl_config": "<Configuration of RTL>",
"rtl_tag": "<Tags for the RTL>",
"rtl_rag": "<Red | Amber | Green>"
},
"flows": [
{
"flow_directory": "<Directory of the Flow>",
"params": {
"<Flow parameter>": "<value>",
"<Flow parameter>": "<value>"
},
"stages": [
{
"name": "<Stage name>",
"tool": {
"name": "<Tool name>",
"version": "<Tool version>"
},
"machine": "<Host name running this stage>",
"collection_mode": "<OFFLINE_FROM_LOGS | DURING_RUN_TIME>",
"status": "<NOT_STARTED | RUNNING | COMPLETED_SUCCESSFULLY | COMPLETED_WITH_ERRORS>",
"log_files": [
"<Absolute path of log file>",
"<Absolute path of log file>"
],
"metrics": {
"<Metric key>": "<value>",
"<Metric key>": "<value>"
}
}
],
"log_files": [
"<Absolute path of log file>",
"<Absolute path of log file>"
]
}
]
}
|
Note
rag: red: no verification ran on the design. amber: alpha or beta release with some levels of verifications. green: release candidate
2.3.2. Database¶
The question now is where do we store this these information? Answer: MongoDB.
2.3.2.1. Starting a MongoDB Server¶
Option 1: Docker
This is the easiest option to get started. Use the following command to start a local database server
docker run -d -p 27017:27017 -v /path/to/local/folder:/data/db --name edaac_db mongo
This will start a local MongoDB server on port 27017
(the default port for MongoDB).
It will also mount a folder at /path/to/local/folder
to the container to persist data when the container is stopped.
Option 2: Install Locally
Follow the instructions on the official documentation.
Option 3: Cloud Instance
Create a MongoDB instance on your cloud provider account using MongoDB Atlas.
2.3.2.2. Connecting to MongoDB¶
After starting the server, download MongoDB Compass to graphically connect to the database and ensure that it is running correctly.
Next, create a database with a give it a name (e.g. test_db) using MongoDB Compass.
From Python, connect to the database using:
import mongoengine as mongo
mongo.connect('test_db')
The above code will connect automatically to a MongoDB server running on the localhost with the default port, username and password.
If you are running a remote MongoDB instance, provide the credentials as below:
import mongoengine as mongo
mongo.connect('test_db', host='', port='', username='', password='')
Note
mongoengine
package is installed as part of edaac
dependencies.
2.3.3. Examples¶
2.3.3.1. Creating a Project¶
The only required key of a project document is its name
.
All other keys can be updated later by retrieving the project, modifying it and then saving it back.
import mongoengine as mongo
from edaac.models import Project, Technology, Design
mongo.connect('test_db')
# create project
project = Project(
name='test-project',
description='demonstrates the use of edaac models',
technology=Technology(
foundry='TestFoundry',
process=45
),
design=Design(
name='test-design',
rtl_files=['/path/to/rtl1.v', '/path/to/rtl2.v'],
netlist_file='/path/to/netlist.v',
sdc_file='/path/to/const.sdc'
)
)
project.save()
mongo.disconnect()
2.3.3.2. Update Project Data¶
The below code retrieves an existing project and updates its data.
import mongoengine as mongo
from edaac.models import Project, Flow, Stage, Design, Tool
from edaac.enum import StageStatus, DataCollectionMode
mongo.connect('test_db')
# retrieve project
project = Project.objects(name='test-project-flows').first()
self.assertIsNotNone(project)
project.design = Design(
name='test-design',
rtl_files=['/path/to/rtl1.v', '/path/to/rtl2.v'],
netlist_file='/path/to/netlist.v',
sdc_file='/path/to/const.sdc'
)
project.flows.append(
Flow(
flow_directory='/path/to/flow/directory',
params={
'param1': 'value1',
'param2': 'value2'
},
stages=[
Stage(
name='synth',
tool=Tool(
name='synth_tool',
version='0.0.0'
),
machine='test-machine',
collection_mode=DataCollectionMode.OFFLINE_FROM_LOGS.name,
status=StageStatus.COMPLETED_SUCCESSFULLY.name,
log_files=['/path/to/log1',
'/path/to/drc', '/path/to/timing'],
metrics={} # should be extracted using edaac.parsers
),
Stage(
name='placement',
tool=Tool(
name='placement_tool',
version='0.0.0'
),
machine='test-machine',
collection_mode=DataCollectionMode.OFFLINE_FROM_LOGS.name,
status=StageStatus.COMPLETED_SUCCESSFULLY.name,
log_files=['/path/to/log1',
'/path/to/drc', '/path/to/timing'],
metrics={} # should be extracted using edaac.parsers
),
Stage(
name='routing',
tool=Tool(
name='routing_tool',
version='0.0.0'
),
machine='test-machine',
collection_mode=DataCollectionMode.OFFLINE_FROM_LOGS.name,
status=StageStatus.COMPLETED_SUCCESSFULLY.name,
log_files=['/path/to/log1',
'/path/to/drc', '/path/to/timing'],
metrics={} # should be extracted using edaac.parsers
)
],
log_files=['/path/to/log1', '/path/to/log2']
)
)
result = project.save()
mongo.disconnect()