﻿<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="thpdoc.xsl"?>
<page id="attributes" noauto = "1">
  <subsection>
	<p>Attributes allow placing compile-time "tags" on ports, signals, entities, classes, etc. and writing generic code iterating through all ports/signals/etc. having a certain tag. E.g. it is possible to mark certain ports of a component as "exported" and then write a generic process making the values of all "exported" ports available through a bus.</p>
	<code>[Attribute1, Attribute2, ..., AttributeN]
class/entity/port/etc
{
	...
}</code>
	<p>Every attribute should be a class derived from System.Attributes.Attribute. To get a list (see <link>lists</link>) of all attributes of a certain primitive, use the <link>__attributes</link> built-in function. To get all ports of an entity (or an instance) having a specified attribute, use the <link>__ports</link> built-in function.</p>
</subsection>
<section name="Built-in attributes">
	THDL++ defines the following built-in attributes:
	<subsection name = "System.Attributes.ExactNaming">
		This attribute disables name all transformations made by VHDL generator and ensures that VHDL port/signal name exactly matches THDL++ port/signal name. Example:
		<code>entity Test
{
	signal logic TestSig1;
	
	[System.Attributes.ExactNaming]
	signal logic TestSig2;
}</code>
Generated code:
<code>architecture Behavioral of Test is
	signal Test_Sig1 : std_logic;
	signal TestSig2 : std_logic;
	
	begin
		
end architecture Behavioral;</code>
	The signal TestSig1 has been converted to Test_Sig1 to improve simulation experience with ISim (ISim converts all signal names to lowercase). Specifying ExactNaming on TestSig2 prevented this.
	</subsection>
</section>
<examples>
	<example name="Exporting ports to a bus">
	Let's sketch a generic wrapper that makes all desired ports of an entity accessible through a bus. First, let's define our attribute class:
	<code>class MyExportable : System.Attributes.Attribute {}</code>
	The class is empty. It is only used to tag something with "MyExportable" and to lookup "everything tagged with MyExportable".<br/>
	Now let's define an entity having several ports (A, B and D) tagged with MyExportable:
	<code>entity MyTestedEntity
{
	port in logic clk;
	[MyExportable]
	port out logic [8] A, B;
	port out logic[8] C;
		
	[MyExportable]
	port out logic[8] D;
}</code>
	Let's also write a wrapper entity:
<code>entity Test
{
	signal logic clk;
	
	MyTestedEntity uut(
		clk = clk,
		A = auto,
		B = auto,
		C = auto,
		D = auto
	);
	
	port in logic[8] Addr;
	port out logic[8] Data;
}</code>
	Finally, let's use attributes! We will define a generic process that allows reading exportable registers using the Addr/Data ports:
<code>	process route (any)
	{
		Data = '-';
		foreach(any s in __ports(uut, MyExportable))
			if (Addr == __foreach_iteration)
				Data = s;
	}</code>
	Generated VHDL code:
<code>		uut : My_Tested_Entity
			port map (
				clk =&gt; clk,
				A =&gt; thp_uut_autosig_A,
				B =&gt; thp_uut_autosig_B,
				C =&gt; thp_uut_autosig_C,
				D =&gt; thp_uut_autosig_D
			);
		
		route : process (Addr, thp_uut_autosig_A, thp_uut_autosig_B, thp_uut_autosig_D) is
		begin
			Data &lt;= (others =&gt; '-');
			if (Addr = X"00") then
				Data &lt;= thp_uut_autosig_A;
			end if;
			if (Addr = X"01") then
				Data &lt;= thp_uut_autosig_B;
			end if;
			if (Addr = X"02") then
				Data &lt;= thp_uut_autosig_D;
			end if;
		end process route;</code>
	</example>
	<example name="Templated attributes">
	Let's modify the previous example to specify the bus address of each port when declaring the ports:
<code>template &lt;int Addr&gt; class MyExportable : System.Attributes.Attribute { }</code>
	The port declaration will now look the following way:
<code>	port in logic clk;
	[MyExportable&lt;0&gt;]
	port out logic [8] A;
	[MyExportable&lt;2&gt;]
	port out logic [8] B;
	port out logic[8] C;
		
	[MyExportable&lt;5&gt;]
	port out logic[8] D;</code>
	Finally, the route process will have to be modified:
	<code>process route (any)
{
	Data = '-';
	foreach(any s in __ports(uut))
	{
		foreach (any a in __attributes(s))
			if (__defined(a.Addr))
				if (Addr == a.Addr)
					Data = s;
	}
}</code>
	</example>
</examples>
  <seealso id="entity"/>
  <seealso id="signal"/>
  <seealso id="port"/>
  <seealso id="class"/>
  <seealso id="__ports"/>
  <seealso id="__attributes"/>
  <seealso id="__defined"/>
  <seealso id="__writable"/>
</page>