Merge pull request #3432 from YosysHQ/aki/jny_updates

jny: Added JNY schema and additional information to JNY output file
This commit is contained in:
Miodrag Milanović 2022-08-03 13:33:10 +02:00 committed by GitHub
commit 3705d8414e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 226 additions and 10 deletions

View File

@ -27,6 +27,8 @@
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <sstream>
#include <iterator>
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
@ -116,17 +118,17 @@ struct JnyWriter
_include_connections(connections), _include_attributes(attributes), _include_properties(properties)
{ }
void write_metadata(Design *design, uint16_t indent_level = 0)
void write_metadata(Design *design, uint16_t indent_level = 0, std::string invk = "")
{
log_assert(design != nullptr);
design->sort();
f << "{\n";
f << " \"$schema\": \"https://raw.githubusercontent.com/YosysHQ/yosys/master/misc/jny.schema.json\",\n";
f << stringf(" \"generator\": \"%s\",\n", escape_string(yosys_version_str).c_str());
// XXX(aki): Replace this with a proper version info eventually:tm:
f << " \"version\": \"0.0.0\",\n";
f << " \"version\": \"0.0.1\",\n";
f << " \"invocation\": \"" << escape_string(invk) << "\",\n";
f << " \"features\": [";
size_t fnum{0};
@ -409,11 +411,12 @@ struct JnyWriter
struct JnyBackend : public Backend {
JnyBackend() : Backend("jny", "generate design metadata") { }
void help() override {
// XXX(aki): TODO: explicitly document the JSON schema
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" jny [options] [selection]\n");
log("\n");
log("Write JSON netlist metadata for the current design\n");
log("\n");
log(" -no-connections\n");
log(" Don't include connection information in the netlist output.\n");
log("\n");
@ -423,8 +426,8 @@ struct JnyBackend : public Backend {
log(" -no-properties\n");
log(" Don't include property information in the netlist output.\n");
log("\n");
log("Write a JSON metadata for the current design\n");
log("\n");
log("The JSON schema for JNY output files is located in the \"jny.schema.json\" file\n");
log("which is located at \"https://raw.githubusercontent.com/YosysHQ/yosys/master/misc/jny.schema.json\"\n");
log("\n");
}
@ -453,12 +456,22 @@ struct JnyBackend : public Backend {
break;
}
// Compose invocation line
std::ostringstream invk;
if (!args.empty()) {
std::copy(args.begin(), args.end(),
std::ostream_iterator<std::string>(invk, " ")
);
}
invk << filename;
extra_args(f, filename, args, argidx);
log_header(design, "Executing jny backend.\n");
JnyWriter jny_writer(*f, false, connections, attributes, properties);
jny_writer.write_metadata(design);
jny_writer.write_metadata(design, 0, invk.str());
}
} JnyBackend;
@ -472,7 +485,7 @@ struct JnyPass : public Pass {
log("\n");
log(" jny [options] [selection]\n");
log("\n");
log("Write a JSON netlist metadata for the current design\n");
log("Write JSON netlist metadata for the current design\n");
log("\n");
log(" -o <filename>\n");
log(" write to the specified file.\n");
@ -520,6 +533,15 @@ struct JnyPass : public Pass {
break;
}
// Compose invocation line
std::ostringstream invk;
if (!args.empty()) {
std::copy(args.begin(), args.end(),
std::ostream_iterator<std::string>(invk, " ")
);
}
extra_args(args, argidx, design);
std::ostream *f;
@ -534,13 +556,14 @@ struct JnyPass : public Pass {
log_error("Can't open file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
}
f = ff;
invk << filename;
} else {
f = &buf;
}
JnyWriter jny_writer(*f, false, connections, attributes, properties);
jny_writer.write_metadata(design);
jny_writer.write_metadata(design, 0, invk.str());
if (!filename.empty()) {
delete f;

193
misc/jny.schema.json Normal file
View File

@ -0,0 +1,193 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://raw.githubusercontent.com/YosysHQ/yosys/master/misc/jny.schema.json",
"title": "Yosys JSON Netlist metadata",
"description": "Yosys JSON Netlist",
"type": "object",
"properties": {
"generator": {
"type": "string",
"description": "JNY File Generator"
},
"version": {
"type": "string",
"description": "JNY Version"
},
"invocation": {
"type": "string",
"description": "Invocation line that generated the JNY metadata"
},
"features": {
"type": "array",
"description": "What information is contained in the JNY file",
"items": {
"type": "string"
}
},
"modules": {
"type": "array",
"items": { "$ref": "#/$defs/module" }
}
},
"required": [
"generator",
"version",
"invocation",
"features"
],
"$defs": {
"module": {
"type": "object",
"description": "Module definition",
"properties": {
"name": {
"type": "string",
"description": "Module Name"
},
"cell_sorts": {
"type": "array",
"description": "",
"items": { "$ref": "#/$defs/cell_sort" }
},
"connections": {
"type": "array",
"description": "Cell connections",
"items": { "$ref": "#/$defs/connection" }
},
"attributes": {
"type": "object",
"description": "Attributes attached to the module"
},
"parameters": {
"type": "object",
"description": "Parameters attached to the module"
}
},
"required": [
"name",
"cell_sorts"
]
},
"cell_sort": {
"type": "object",
"description": "Describes a type of cell",
"properties": {
"type": {
"type": "string",
"description": "Type of cell"
},
"ports": {
"type": "array",
"description": "Cell ports",
"items": { "$ref": "#/$defs/port" }
}
,
"cells": {
"type": "array",
"description": "Cells of cell_sort",
"items": { "$ref": "#/$defs/cell" }
}
},
"required": [
"type",
"ports",
"cells"
]
},
"connection": {
"type": "object",
"description": "A connection within a module or cell",
"properties": {
"name": {
"type": "string",
"description": "Connection name"
},
"signals": {
"type": "array",
"description": "Signals that compose the connection",
"items": { "$ref": "#/$defs/signal" }
}
},
"required": [
"name",
"signals"
]
},
"port": {
"type": "object",
"description": "Cell port description",
"properties": {
"name": {
"type": "string",
"description": "Port name"
},
"direction": {
"type": "string",
"description": "Port direction",
"enum": ["i", "o", "io", ""]
},
"range": {
"type": "array",
"description": "Port width [MSB, LSB]",
"items": {
"type": "number"
},
"minContains": 1,
"maxContains": 2
}
},
"required": [
"name",
"direction",
"range"
]
},
"cell": {
"type": "object",
"description": "Module cell definition",
"properties": {
"name": {
"type": "string",
"description": "Cell name"
},
"connections": {
"type": "array",
"description": "Cell connections",
"items": { "$ref": "#/$defs/connection" }
},
"attributes": {
"type": "object",
"description": "Attributes attached to the cell"
},
"parameters": {
"type": "object",
"description": "Parameters attached to the cell"
}
},
"required": [
"name"
]
},
"signal": {
"type": "object",
"description": "A signal definition",
"parameters": {
"width": {
"type": "string"
},
"type": {
"type": "string",
"enum": ["wire", "chunk"]
},
"const": {
"type": "boolean"
}
},
"required": [
"width",
"type",
"const"
]
}
}
}