
{"id":61,"date":"2018-09-11T14:33:31","date_gmt":"2018-09-11T14:33:31","guid":{"rendered":"http:\/\/blogs.plymouth.ac.uk\/embedded-systems\/?page_id=61"},"modified":"2018-09-12T13:32:36","modified_gmt":"2018-09-12T13:32:36","slug":"part-2-multiple-architectures","status":"publish","type":"page","link":"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/fpga-and-vhdl\/test-benches\/part-2-multiple-architectures\/","title":{"rendered":"Part 2 &#8211; Multiple Architectures"},"content":{"rendered":"<p><a href=\"http:\/\/blogs.plymouth.ac.uk\/embedded-systems\/fpga-and-vhdl\/test-benches\/part-1-single-architecture-test\/\">prev<\/a><\/p>\n<p>In the previous section, we looked at testing a single component with a single architecture. We are now going to look at how to test multiple architectures.<\/p>\n<p>Any given entity can have one or more architectures. There are a number of reasons why you might do this, including:<\/p>\n<ul>\n<li>Some architectures may be optimised for space, while others are chosen for speed<\/li>\n<li>Some may use different styles of VHDL &#8211; the first might use behavioural VHDL to get the function quickly defined. You might then add another that uses structural VHDL. As you develop this, you can compare outputs to help test your second design.<\/li>\n<li>Some may exhibit different timing characteristics &#8211; such as hazards<\/li>\n<li>You might create additional architectures with additional test facilities<\/li>\n<\/ul>\n<h2>Component with Two Architectures<\/h2>\n<p>Continuing with the theme from the previous section, we now modify the component to add an additional architecture. The intention is that this second architecture is functionally identical to the first (I&#8217;ve simply applied DeMorgan&#8217;s theorem). However, to make an important point, <strong>I&#8217;ve purposely left an error in the second architecture<\/strong>.<\/p>\n<p>Here is the modified component with the second architecture included:<\/p>\n<div>\n<pre class=\"theme:xcode lang:default highlight:0 decode:true\">library ieee;\t\t\t\t\r\nuse ieee.std_logic_1164.all;\r\n--use ieee.std_logic_unsigned.all;\r\n\r\n-- Component 1 - very simple device that performs a logical OR on three single bit inputs\r\nentity comp1 is\r\nport(  \tA:\tin std_logic;\r\n\tB:\tin std_logic;\r\n\tC:\tin std_logic;\r\n\tY:\tout std_logic\r\n);\r\nend comp1;\r\n\r\n--This component has two architecture\r\narchitecture v1 of comp1 is\r\nbegin\r\n\ty &lt;= A or B or C;\r\nend v1;\r\n\r\n--This second version is supposed to be functionally equivalent\r\n--HOWEVER, there is a bug\r\narchitecture v2 of comp1 is\r\nbegin\r\n\ty &lt;= (not A) and (not B) and  (not C);\r\nend v2;<\/pre>\n<\/div>\n<div>Note the names of the two architectures, <code>v1<\/code> and <code>v2<\/code>.<\/div>\n<h2>Testbench<\/h2>\n<p>We are now going to instantiate both versions of the <code>comp1<\/code> component and compare their outputs in a testbench. The VHDL code is shown below<\/p>\n<pre class=\"theme:xcode lang:default highlight:0 decode:true\">library ieee;\t\t\t\t\r\nuse ieee.std_logic_1164.all;\r\nuse ieee.numeric_std.all;\r\n--use ieee.std_logic_unsigned.all;\r\n--use std.textio.all;\r\n\r\nentity comp1_test is\r\nend comp1_test;\r\n\r\narchitecture inst1 of comp1_test is\r\n\r\n\t--Declare signals\r\n\tsignal AA : std_logic;\r\n\tsignal BB : std_logic;\r\n\tsignal CC : std_logic;\r\n\tsignal Y1 : std_logic;\t--output for version 1\r\n\tsignal Y2 : std_logic;\t--output for version 2\r\n\t\r\nbegin\r\n\t--Instantiate v1 of the component type comp1\r\n\tu1: entity work.comp1(v1) PORT MAP (\r\n\t\tA =&gt; AA,\r\n\t\tB =&gt; BB,\r\n\t\tC =&gt; CC,\r\n\t\tY =&gt; Y1\r\n\t);\r\n\r\n\t--Instantiate v2 of the component type comp1\r\n\tu2: entity work.comp1(v2) PORT MAP (\r\n\t\tA =&gt; AA,\r\n\t\tB =&gt; BB,\r\n\t\tC =&gt; CC,\r\n\t\tY =&gt; Y2\r\n\t);\r\n\r\n\tcomp1_process:\r\n\tprocess \r\n\t\tvariable count : std_logic_vector(2 downto 0);\r\n\tbegin\t\r\n\t\t--Exhaustive test\r\n\t\tfor idx in 0 to 7 loop\r\n\t\t\t--Convert integer idx to std_logic\r\n\t\t\tcount := std_logic_vector(to_unsigned(idx,3));\r\n\r\n\t\t\t--Assign internal signals to the individual bits of count\r\n\t\t\tAA &lt;= count(0);\r\n\t\t\tBB &lt;= count(1);\r\n\t\t\tCC &lt;= count(2);\r\n\r\n\t\t\t--Wait for 20ns (also prompts signals to update)\r\n\t\t\twait for 20 ns;\r\n\t\tend loop;\r\n\t\t\r\n\t\t--End of test is to wait forever\r\n\t\twait;\r\n\tend process;\r\n\t\t\r\nend inst1;<\/pre>\n<div>Note the key differences here:<\/div>\n<ul>\n<li>The component declaration has been dropped (it&#8217;s optional in this case)<\/li>\n<li>The syntax for instantiation now has changed.<\/li>\n<\/ul>\n<div>Let&#8217;s take a closer look at how we instantiate a component with a specific architecture:<\/div>\n<pre class=\"theme:xcode lang:default highlight:0 decode:true\">u1: entity work.comp1(v1) PORT MAP (\r\n\t\tA =&gt; AA,\r\n\t\tB =&gt; BB,\r\n\t\tC =&gt; CC,\r\n\t\tY =&gt; Y1 );<\/pre>\n<div>Note the addition of the <code>entity<\/code> keyword, followed by a more explicit reference to the component under test: <code>work.comp1(v1)<\/code>. The second instance is similar:<\/div>\n<pre class=\"theme:xcode lang:default highlight:0 decode:true\">u2: entity work.comp1(v2) PORT MAP (\r\n\tA =&gt; AA,\r\n\tB =&gt; BB,\r\n\tC =&gt; CC,\r\n\tY =&gt; Y2 );<\/pre>\n<div>This is a separate instance, labelled <code>u2<\/code>. It&#8217;s as if a second component has added to a schematic and wired to the same input signals (AA,BB and CC). Note however that the outputs are connected to two separate signals, <code>Y1<\/code> and <code>Y2<\/code>. We can now visually compare these signals with ModelSim. The output of the testbench is shown below:<\/div>\n<div>\n<figure id=\"attachment_78\" aria-describedby=\"caption-attachment-78\" style=\"width: 826px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-78 size-full\" src=\"http:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/09\/snapshot1.png\" alt=\"\" width=\"826\" height=\"617\" srcset=\"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/09\/snapshot1.png 826w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/09\/snapshot1-300x224.png 300w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/09\/snapshot1-768x574.png 768w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/09\/snapshot1-560x418.png 560w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/09\/snapshot1-260x194.png 260w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/09\/snapshot1-160x120.png 160w\" sizes=\"auto, (max-width: 826px) 100vw, 826px\" \/><figcaption id=\"caption-attachment-78\" class=\"wp-caption-text\">Showing the output of the two architectures, highlighting an error in the second.<\/figcaption><\/figure>\n<p>You can see from the figure above that the outputs differ, and that one is the logical inverse of the other. I have indeed forgotten to invert the result when I performed DeMorgan&#8217;s.<\/p>\n<\/div>\n<h3>Corrected Version<\/h3>\n<p>The corrected v2 architecture is shown below:<\/p>\n<figure id=\"attachment_79\" aria-describedby=\"caption-attachment-79\" style=\"width: 826px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-79\" src=\"http:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/09\/snapshot2.png\" alt=\"\" width=\"826\" height=\"617\" srcset=\"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/09\/snapshot2.png 826w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/09\/snapshot2-300x224.png 300w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/09\/snapshot2-768x574.png 768w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/09\/snapshot2-560x418.png 560w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/09\/snapshot2-260x194.png 260w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/09\/snapshot2-160x120.png 160w\" sizes=\"auto, (max-width: 826px) 100vw, 826px\" \/><figcaption id=\"caption-attachment-79\" class=\"wp-caption-text\">Showing the outputs of the two architectures to be logically equivalent<\/figcaption><\/figure>\n<div>The simulation result above illustrates that both architectures are at least functionally equivalent. This does not mean they will behave in exactly the same way when synthesised of course. We would need to factor in propagation delay to check timing characteristics.<\/div>\n<div><\/div>\n<div><a href=\"http:\/\/blogs.plymouth.ac.uk\/embedded-systems\/fpga-and-vhdl\/test-benches\/part-3-automatic-testing-with-assert\/\">Next<\/a> &#8211; automating tests using the assert command<\/div>\n<div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>prev In the previous section, we looked at testing a single component with a single architecture. We are now going to look at how to test multiple architectures. Any given entity can have one or more architectures. There are a number of reasons why you might do this, including: Some architectures may be optimised for&hellip; <a class=\"more-link\" href=\"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/fpga-and-vhdl\/test-benches\/part-2-multiple-architectures\/\">Continue reading <span class=\"screen-reader-text\">Part 2 &#8211; Multiple Architectures<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":30,"menu_order":1,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-61","page","type-page","status-publish","hentry","entry"],"_links":{"self":[{"href":"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-json\/wp\/v2\/pages\/61","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-json\/wp\/v2\/comments?post=61"}],"version-history":[{"count":8,"href":"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-json\/wp\/v2\/pages\/61\/revisions"}],"predecessor-version":[{"id":90,"href":"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-json\/wp\/v2\/pages\/61\/revisions\/90"}],"up":[{"embeddable":true,"href":"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-json\/wp\/v2\/pages\/30"}],"wp:attachment":[{"href":"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-json\/wp\/v2\/media?parent=61"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}