mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-29 18:52:30 +00:00 
			
		
		
		
	Docs: Add cell reference
Subclass the command reference code in order to support smart references to the internal cells.
This commit is contained in:
		
							parent
							
								
									c98d134662
								
							
						
					
					
						commit
						f9b4e04fef
					
				
					 2 changed files with 59 additions and 43 deletions
				
			
		|  | @ -1,30 +1,5 @@ | ||||||
| # based on https://github.com/ofosos/sphinxrecipes/blob/master/sphinxrecipes/sphinxrecipes.py | # based on https://github.com/ofosos/sphinxrecipes/blob/master/sphinxrecipes/sphinxrecipes.py | ||||||
| # license: |  | ||||||
| # Copyright 2019 Mark Meyer |  | ||||||
| #  |  | ||||||
| # Permission is hereby granted, free of charge, to any person obtaining |  | ||||||
| # a copy of this software and associated documentation files (the |  | ||||||
| # "Software"), to deal in the Software without restriction, including |  | ||||||
| # without limitation the rights to use, copy, modify, merge, publish, |  | ||||||
| # distribute, sublicense, and/or sell copies of the Software, and to |  | ||||||
| # permit persons to whom the Software is furnished to do so, subject to |  | ||||||
| # the following conditions: |  | ||||||
| #  |  | ||||||
| # The above copyright notice and this permission notice shall be |  | ||||||
| # included in all copies or substantial portions of the Software. |  | ||||||
| #  |  | ||||||
| # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |  | ||||||
| # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |  | ||||||
| # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |  | ||||||
| # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |  | ||||||
| # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |  | ||||||
| # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |  | ||||||
| # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |  | ||||||
| 
 | 
 | ||||||
| import docutils |  | ||||||
| from docutils import nodes |  | ||||||
| import sphinx |  | ||||||
| from docutils.parsers import rst |  | ||||||
| from docutils.parsers.rst import directives | from docutils.parsers.rst import directives | ||||||
| from sphinx.domains import Domain, Index | from sphinx.domains import Domain, Index | ||||||
| from sphinx.domains.std import StandardDomain | from sphinx.domains.std import StandardDomain | ||||||
|  | @ -35,7 +10,8 @@ from sphinx import addnodes | ||||||
| 
 | 
 | ||||||
| class CommandNode(ObjectDescription): | class CommandNode(ObjectDescription): | ||||||
|     """A custom node that describes a command.""" |     """A custom node that describes a command.""" | ||||||
|    | 
 | ||||||
|  |     name = 'cmd' | ||||||
|     required_arguments = 1 |     required_arguments = 1 | ||||||
| 
 | 
 | ||||||
|     option_spec = { |     option_spec = { | ||||||
|  | @ -49,24 +25,29 @@ class CommandNode(ObjectDescription): | ||||||
|         return sig |         return sig | ||||||
| 
 | 
 | ||||||
|     def add_target_and_index(self, name_cls, sig, signode): |     def add_target_and_index(self, name_cls, sig, signode): | ||||||
|         signode['ids'].append('cmd' + '-' + sig) |         signode['ids'].append(type(self).name + '-' + sig) | ||||||
|         if 'noindex' not in self.options: |         if 'noindex' not in self.options: | ||||||
|             name = "{}.{}.{}".format('cmd', type(self).__name__, sig) |             name = "{}.{}.{}".format(self.name, type(self).__name__, sig) | ||||||
|             tagmap = self.env.domaindata['cmd']['obj2tag'] |             tagmap = self.env.domaindata[type(self).name]['obj2tag'] | ||||||
|             tagmap[name] = list(self.options.get('tags', '').split(' ')) |             tagmap[name] = list(self.options.get('tags', '').split(' ')) | ||||||
|             title = self.options.get('title') |             title = self.options.get('title') | ||||||
|             titlemap = self.env.domaindata['cmd']['obj2title'] |             titlemap = self.env.domaindata[type(self).name]['obj2title'] | ||||||
|             titlemap[name] = title |             titlemap[name] = title | ||||||
|             objs = self.env.domaindata['cmd']['objects'] |             objs = self.env.domaindata[type(self).name]['objects'] | ||||||
|             objs.append((name, |             objs.append((name, | ||||||
|                          sig, |                          sig, | ||||||
|                          title, |                          title, | ||||||
|                          self.env.docname, |                          self.env.docname, | ||||||
|                          'cmd' + '-' + sig, |                          type(self).name + '-' + sig, | ||||||
|                          0)) |                          0)) | ||||||
| 
 | 
 | ||||||
|  | class CellNode(CommandNode): | ||||||
|  |     """A custom node that describes an internal cell.""" | ||||||
|  | 
 | ||||||
|  |     name = 'cell' | ||||||
|  | 
 | ||||||
| class TagIndex(Index): | class TagIndex(Index): | ||||||
|     """A custom directive that creates an tag matrix.""" |     """A custom directive that creates a tag matrix.""" | ||||||
|      |      | ||||||
|     name = 'tag' |     name = 'tag' | ||||||
|     localname = 'Tag Index' |     localname = 'Tag Index' | ||||||
|  | @ -167,7 +148,7 @@ class CommandIndex(Index): | ||||||
|                  in self.domain.get_objects()) |                  in self.domain.get_objects()) | ||||||
|         items = sorted(items, key=lambda item: item[0]) |         items = sorted(items, key=lambda item: item[0]) | ||||||
|         for name, dispname, typ, docname, anchor in items: |         for name, dispname, typ, docname, anchor in items: | ||||||
|             lis = content.setdefault('Command', []) |             lis = content.setdefault(self.shortname, []) | ||||||
|             lis.append(( |             lis.append(( | ||||||
|                 dispname, 0, docname, |                 dispname, 0, docname, | ||||||
|                 anchor, |                 anchor, | ||||||
|  | @ -177,10 +158,14 @@ class CommandIndex(Index): | ||||||
| 
 | 
 | ||||||
|         return (re, True) |         return (re, True) | ||||||
| 
 | 
 | ||||||
|  | class CellIndex(CommandIndex): | ||||||
|  |     name = 'cell' | ||||||
|  |     localname = 'Internal cell reference' | ||||||
|  |     shortname = 'Internal cell' | ||||||
| 
 | 
 | ||||||
| class CommandDomain(Domain): | class CommandDomain(Domain): | ||||||
|     name = 'cmd' |     name = 'cmd' | ||||||
|     label = 'Command Sample' |     label = 'Yosys commands' | ||||||
| 
 | 
 | ||||||
|     roles = { |     roles = { | ||||||
|         'ref': XRefRole() |         'ref': XRefRole() | ||||||
|  | @ -203,7 +188,7 @@ class CommandDomain(Domain): | ||||||
| 
 | 
 | ||||||
|     def get_full_qualified_name(self, node): |     def get_full_qualified_name(self, node): | ||||||
|         """Return full qualified name for a given node""" |         """Return full qualified name for a given node""" | ||||||
|         return "{}.{}.{}".format('cmd', |         return "{}.{}.{}".format(type(self).name, | ||||||
|                                  type(node).__name__, |                                  type(node).__name__, | ||||||
|                                  node.arguments[0]) |                                  node.arguments[0]) | ||||||
| 
 | 
 | ||||||
|  | @ -229,18 +214,40 @@ class CommandDomain(Domain): | ||||||
|         else: |         else: | ||||||
|             print(f"Missing ref for {target} in {fromdocname} ") |             print(f"Missing ref for {target} in {fromdocname} ") | ||||||
|             return None |             return None | ||||||
|  |          | ||||||
|  | class CellDomain(CommandDomain): | ||||||
|  |     name = 'cell' | ||||||
|  |     label = 'Yosys internal cells' | ||||||
|  | 
 | ||||||
|  |     directives = { | ||||||
|  |         'def': CellNode, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     indices = { | ||||||
|  |         CellIndex, | ||||||
|  |         TagIndex | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
| def setup(app): | def setup(app): | ||||||
|     app.add_domain(CommandDomain) |     app.add_domain(CommandDomain) | ||||||
|  |     app.add_domain(CellDomain) | ||||||
| 
 | 
 | ||||||
|     StandardDomain.initial_data['labels']['commandindex'] =\ |     StandardDomain.initial_data['labels']['commandindex'] =\ | ||||||
|         ('cmd-cmd', '', 'Command Reference') |         ('cmd-cmd', '', 'Command Reference') | ||||||
|     StandardDomain.initial_data['labels']['tagindex'] =\ |     StandardDomain.initial_data['labels']['tagindex'] =\ | ||||||
|         ('cmd-tag', '', 'Tag Index') |         ('cmd-tag', '', 'Tag Index') | ||||||
|  |     StandardDomain.initial_data['labels']['cellindex'] =\ | ||||||
|  |         ('cell-cell', '', 'Internal cell reference') | ||||||
|  |     StandardDomain.initial_data['labels']['tagindex'] =\ | ||||||
|  |         ('cell-tag', '', 'Tag Index') | ||||||
| 
 | 
 | ||||||
|     StandardDomain.initial_data['anonlabels']['commandindex'] =\ |     StandardDomain.initial_data['anonlabels']['commandindex'] =\ | ||||||
|         ('cmd-cmd', '') |         ('cmd-cmd', '') | ||||||
|     StandardDomain.initial_data['anonlabels']['tagindex'] =\ |     StandardDomain.initial_data['anonlabels']['tagindex'] =\ | ||||||
|         ('cmd-tag', '') |         ('cmd-tag', '') | ||||||
|  |     StandardDomain.initial_data['anonlabels']['cellindex'] =\ | ||||||
|  |         ('cell-cell', '') | ||||||
|  |     StandardDomain.initial_data['anonlabels']['tagindex'] =\ | ||||||
|  |         ('cell-tag', '') | ||||||
|      |      | ||||||
|     return {'version': '0.1'} |     return {'version': '0.2'} | ||||||
|  |  | ||||||
|  | @ -899,17 +899,26 @@ struct HelpPass : public Pass { | ||||||
| 		fprintf(f, "%s\n", title_line.c_str()); | 		fprintf(f, "%s\n", title_line.c_str()); | ||||||
| 		fprintf(f, "%s\n", underline.c_str()); | 		fprintf(f, "%s\n", underline.c_str()); | ||||||
| 
 | 
 | ||||||
| 		// help text
 | 		// help text, with cell def for links
 | ||||||
| 		fprintf(f, "%s\n\n", cell.desc.c_str()); | 		fprintf(f, ".. cell:def:: %s\n", cell.name.c_str()); | ||||||
|  | 		if (cell.title.length()) | ||||||
|  | 			fprintf(f, "   :title: %s\n\n", cell.title.c_str()); | ||||||
|  | 		else | ||||||
|  | 			fprintf(f, "   :title: %s\n\n", cell.name.c_str()); | ||||||
|  | 		std::stringstream ss; | ||||||
|  | 		ss << cell.desc; | ||||||
|  | 		for (std::string line; std::getline(ss, line, '\n');) { | ||||||
|  | 			fprintf(f, "   %s\n", line.c_str()); | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		// source code
 | 		// source code
 | ||||||
| 		fprintf(f, "Simulation model (Verilog)\n"); | 		fprintf(f, "\nSimulation model (Verilog)\n"); | ||||||
| 		fprintf(f, "--------------------------\n\n"); | 		fprintf(f, "--------------------------\n\n"); | ||||||
| 		fprintf(f, ".. code-block:: verilog\n"); | 		fprintf(f, ".. code-block:: verilog\n"); | ||||||
| 		fprintf(f, "   :caption: %s\n\n", cell.source.c_str()); | 		fprintf(f, "   :caption: %s\n\n", cell.source.c_str()); | ||||||
| 		std::stringstream ss; | 		std::stringstream ss2; | ||||||
| 		ss << cell.code; | 		ss2 << cell.code; | ||||||
| 		for (std::string line; std::getline(ss, line, '\n');) { | 		for (std::string line; std::getline(ss2, line, '\n');) { | ||||||
| 			fprintf(f, "   %s\n", line.c_str()); | 			fprintf(f, "   %s\n", line.c_str()); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue