{"id":272,"date":"2013-12-01T17:35:13","date_gmt":"2013-12-01T15:35:13","guid":{"rendered":"http:\/\/www.viesurip.fr\/?page_id=272"},"modified":"2013-12-01T17:37:03","modified_gmt":"2013-12-01T15:37:03","slug":"memo-vhdl","status":"publish","type":"page","link":"https:\/\/www.viesurip.fr\/en\/mes-projets\/memos\/memo-vhdl\/","title":{"rendered":"VHDL cheat sheet"},"content":{"rendered":"<p>All the code in this cheat sheet is synthesizable, except in the part about simulation.<\/p>\n<h2>Data types<\/h2>\n<p>All signals, inputs, outputs and constants have a type in VHDL.<\/p>\n<pre class=\"brush: vhdl; title: ; notranslate\" title=\"\">\r\n-- Signal of one bit (no arithmetic)\r\nsignal my_signal: std_logic;\r\n-- Signal of 4 bits (no arithmetic)\r\nsignal my_bus: std_logic_vector(3 down to 0);\r\n\r\n-- Signal of 12 bits made to store unsigned integers\r\nsignal my_count: unsigned(11 downto 0);\r\n-- Signal of 10 bits made to store signed integers\r\nsignal my_number: signed(9 downto 0);\r\n<\/pre>\n<h2>Basic structure<\/h2>\n<p>One file per entity, with this skeleton:<\/p>\n<pre class=\"brush: vhdl; title: ; notranslate\" title=\"\">\r\n----------------------------------------------------------------\r\n-- Lines starting with  -- are comments\r\n--\r\n-- Always put a comment explaining the role of the\r\n-- entity at the top of the file\r\n----------------------------------------------------------------\r\n\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\nuse IEEE.NUMERIC_STD.ALL; -- required for signed\/unsigned\r\n\r\nentity my_example_entity is\r\n    generic (\r\n        -- Constant parameters that can be used in code below (optional)\r\n        PARAM_ONE : std_logic_vector(7 downto 0) := x&quot;01&quot;;\r\n        PARAM_TWO : std_logic_vector(7 downto 0) := x&quot;02&quot;\r\n    );\r\n    port(\r\n        -- Input and output ports of the entity\r\n        -- Only std_logic and std_logic_vector types are accepted here\r\n        CLK      : in std_logic;\r\n        RESET    : in std_logic;\r\n        DATA_OUT : out std_logic_vector(7 downto 0);\r\n    );\r\nend my_example_entity;\r\n\r\narchitecture Behavioral of my_example_entity is\r\n    -- Declaration of internal signals\r\n    signal store_conf : std_logic;\r\nbegin\r\n\r\n    -- Here goes the code describing the behavior of the entity\r\n    -- This is where most of the code is written\r\n\r\nend Behavioral;\r\n<\/pre>\n<h2>Processes<\/h2>\n<p>All processes in an entity are executed in parallel. They can describe synchronous or combinatorial circuit parts.<\/p>\n<pre class=\"brush: vhdl; title: ; notranslate\" title=\"\">\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\n\r\nentity process_examples is\r\n    port(\r\n        CLK    : in std_logic;\r\n        RESET  : in std_logic;\r\n        A      : in std_logic;\r\n        B      : in std_logic;\r\n        RESULT : out std_logic_vector(2 downto 0);\r\n    );\r\nend process_examples;\r\n\r\narchitecture Behavioral of process_examples is\r\nbegin\r\n\r\n    -- Synchronous circuit without reset.\r\n    -- RESULT(0) is updated at each rising edge of CLK\r\n    -- if A or B changed during the last clock cycle.\r\n    process(CLK) begin\r\n        if rising_edge(CLK) then\r\n            RESULT(0) &lt;= A and B;\r\n        end if;\r\n    end process;\r\n\r\n    -- Synchronous circuit with asynchronous reset active at 1.\r\n    -- RESULT(1) is updated at each rising edge of CLK\r\n    -- if A or B changed during the last clock cycle.\r\n    -- Its initial value is set to 0 immediately when RESET is set to 1.\r\n    process(CLK, RESET) begin\r\n        if RESET = '1' then\r\n            RESULT(1) &lt;= '0';\r\n        elsif rising_edge(CLK) then\r\n            RESULT(1) &lt;= A and B;\r\n        end if;\r\n    end process;\r\n\r\n    -- Combinatorial circuit.\r\n    -- RESULT(2) is updated immediately when A or B changes.\r\n    process(A, B) begin -- Sensitivity list: ALL read signals\r\n        RESULT(2) &lt;= A and B;\r\n    end process;\r\n\r\nend Behavioral;\r\n<\/pre>\n<h2>Combinatorial shortcuts<\/h2>\n<p>Processes can be avoided for simple combinatorial circuits.<\/p>\n<pre class=\"brush: vhdl; title: ; notranslate\" title=\"\">\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\n\r\nentity shortcut_examples is\r\n    port(\r\n        DATA_IN  : in std_logic_vector(2 downto 0);\r\n        DATA_OUT : out std_logic_vector(1 downto 0);\r\n        AND_OUT  : out std_logic;\r\n    );\r\nend shortcut_examples;\r\n\r\narchitecture Behavioral of shortcut_examples is\r\nbegin\r\n\r\n    -- The line below\r\n    AND_OUT &lt;= DATA_IN(0) and (DATA_IN(1) or DATA_IN(2));\r\n    -- is equivalent to the process below\r\n    process(DATA_IN) begin\r\n        AND_OUT &lt;= DATA_IN(0) and (DATA_IN(1) or DATA_IN(2));\r\n    end process;\r\n\r\n    -- The line below\r\n    DATA_OUT &lt;= &quot;01&quot; when DATA_IN = &quot;001&quot; else\r\n        (&quot;10&quot; when DATA_IN = &quot;010&quot; else &quot;11&quot;);\r\n    -- is equivalent to the process below\r\n    process(DATA_IN) begin\r\n        case DATA_IN is\r\n            when &quot;001&quot; =&gt;\r\n                DATA_OUT &lt;= &quot;01&quot;;\r\n            when &quot;010&quot; =&gt;\r\n                DATA_OUT &lt;= &quot;10&quot;;\r\n            when others =&gt;\r\n                DATA_OUT &lt;= &quot;11&quot;;\r\n    end process;\r\n\r\nend Behavioral;\r\n<\/pre>\n<h2>Data manipulation<\/h2>\n<pre class=\"brush: vhdl; title: ; notranslate\" title=\"\">\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\nuse IEEE.NUMERIC_STD.ALL;\r\n\r\nentity manip_examples is\r\n    port(\r\n        MSB    : in std_logic_vector(2 downto 0);\r\n        LSB    : in std_logic_vector(3 downto 0);\r\n        RESULT : out std_logic;\r\n    );\r\nend manip_examples;\r\n\r\narchitecture Behavioral of manip_examples is\r\n    signal to_add: unsigned(6 downto 0);\r\n    signal input_bits: std_logic_vector(6 downto 0);\r\n    signal input_value: unsigned(6 downto 0);\r\n    signal sum: unsigned(6 downto 0);\r\n    signal sum_bits: std_logic_vector(6 downto 0);\r\nbegin\r\n\r\n    process begin\r\n        -- Set a bus of any size to 0\r\n        to_add &lt;= (others =&gt; '0');\r\n        -- Set only bits 1, 2 and 3 of a bus\r\n        to_add(3 downto 1) &lt;= &quot;101&quot;;\r\n        -- Set a bus of any size to &quot;11&quot;\r\n        to_add &lt;= (0 =&gt; '1', 1 =&gt; '1', others &lt;= '0');\r\n    end process;\r\n\r\n    -- Merge two buses\r\n    input_bits &lt;= MSB &amp; LSB;\r\n    -- Convert std_logic_vector to unsigned\r\n    input_value &lt;= unsigned(input_bits);\r\n    -- Add two unsigned values (does not work with std_logic_vector)\r\n    sum &lt;= input_value + to_add;\r\n    -- Convert from unsigned to std_logic_vector\r\n    sum_bits &lt;= std_logic_vector(sum);\r\n    -- Select bit with index 3 in a bus\r\n    RESULT &lt;= sum_bits(3);\r\nend Behavioral;\r\n<\/pre>\n<h2>Instantiating an entity<\/h2>\n<p>An entity can be used as part of another. This is how complex systems are done. Here is an example instantiating the entity of the first example. Entities have to be in the same project so that the right definition file is found.<\/p>\n<pre class=\"brush: vhdl; title: ; notranslate\" title=\"\">\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\n\r\nentity my_including_entity is\r\n    port(\r\n        -- Input and output ports of the entity\r\n        -- Only std_logic and std_logic_vector types are accepted here\r\n        CLK      : in std_logic;\r\n        RESET    : in std_logic;\r\n        XOR_OUT : out std_logic_vector(7 downto 0);\r\n    );\r\nend my_including_entity;\r\n\r\narchitecture Behavioral of my_including_entity is\r\n    -- Declaration of the included entity, with its interface\r\n    -- It should be identical to the one in the original file\r\n    component my_example_entity\r\n    generic (\r\n        -- Constant parameters that can be used in code below (optional)\r\n        PARAM_ONE : std_logic_vector(7 downto 0) := x&quot;01&quot;;\r\n        PARAM_TWO : std_logic_vector(7 downto 0) := x&quot;02&quot;\r\n    );\r\n    port(\r\n        -- Input and output ports of the entity\r\n        -- Only std_logic and std_logic_vector types are accepted here\r\n        CLK      : in std_logic;\r\n        RESET    : in std_logic;\r\n        DATA_OUT : out std_logic_vector(7 downto 0);\r\n    );\r\n    end component;\r\n    -- Internal signal to connect to the entity\r\n    signal data_out : std_logic_vector(7 downto 0);\r\nbegin\r\n\r\n    -- Connect the entity\r\n    -- with generic parameters and\r\n    -- internal signals\r\n    my_entity: my_example_entity\r\n    generic map (\r\n        PARAM_ONE =&gt; x&quot;10&quot;,\r\n        PARAM_TWO =&gt; x&quot;02&quot;\r\n    )\r\n    port map (\r\n        CLK =&gt; CLK,\r\n        RESET =&gt; RESET,\r\n        DATA_OUT =&gt; data_out\r\n    );\r\n\r\n    -- Use the output of the entity\r\n    XOR_OUT &lt;= DATA_OUT(0) xor DATA_OUT(5);\r\nend Behavioral;\r\n<\/pre>\n<h2>Simulation test bench<\/h2>\n<p>To test an instance, simultation data must be specified for each of its input signals. This is done by creating a specific VHDL entity with no input or output, called test bench.<br \/>\nSome special commands can be used in test benches, but not in synthesizable VHDL. Here is an example of test bench for the first example entity:<\/p>\n<pre class=\"brush: vhdl; title: ; notranslate\" title=\"\">\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\n\r\nentity testbench is\r\nend testbench;\r\n\r\narchitecture Behavioral of testbench is\r\n    -- Declaration of the simulated entity\r\n    component my_example_entity\r\n    generic (\r\n        -- Constant parameters that can be used in code below (optional)\r\n        PARAM_ONE : std_logic_vector(7 downto 0) := x&quot;01&quot;;\r\n        PARAM_TWO : std_logic_vector(7 downto 0) := x&quot;02&quot;\r\n    );\r\n    port(\r\n        -- Input and output ports of the entity\r\n        -- Only std_logic and std_logic_vector types are accepted here\r\n        CLK      : in std_logic;\r\n        RESET    : in std_logic;\r\n        DATA_OUT : out std_logic_vector(7 downto 0);\r\n    );\r\n    end component;\r\n    -- One signal for each input and output\r\n    -- Signals used as inputs have default values\r\n    signal clk      : std_logic := '0';\r\n    signal reset    : std_logic := '1';\r\n    signal data_out : std_logic_vector(7 downto 0);\r\nbegin\r\n\r\n    -- Connect the entity\r\n    my_entity: my_example_entity\r\n    generic map (\r\n        PARAM_ONE =&gt; x&quot;10&quot;,\r\n        PARAM_TWO =&gt; x&quot;02&quot;\r\n    )\r\n    port map (\r\n        CLK =&gt; clk,\r\n        RESET =&gt; reset,\r\n        DATA_OUT =&gt; data_out\r\n    );\r\n\r\n    -- Generate a fake clock with a period of 8 ns\r\n    clk &lt;= not clk after 4 ns;\r\n    -- Describe a scenario for input values\r\n    process begin\r\n        -- Wait during 5 clock cycles\r\n        wait for 40 ns;\r\n        -- Deactivate the reset\r\n        reset &lt;= '0';\r\n        -- Wait during 50 clock cycles\r\n        wait for 400 ns;\r\n        -- Reactivate the reset\r\n        reset &lt;= '1';\r\n    end process;\r\nend Behavioral;\r\n<\/pre>\n<h2>Useful examples<\/h2>\n<h3>Counter<\/h3>\n<pre class=\"brush: vhdl; title: ; notranslate\" title=\"\">\r\n--------------------------------------\r\n-- Counter with an output on 4 bits.\r\n-- Starts at 0, counts when enable is 1.\r\n-- Stops at generic MAX parameter.\r\n-- Asynchronous reset active at 1\r\n--------------------------------------\r\n\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\nuse IEEE.NUMERIC_STD.ALL;\r\n\r\nentity counter is\r\n    generic (\r\n        MAX: unsigned(3 downto 0) := &quot;1100&quot;\r\n    );\r\n    port(\r\n        CLK    : in std_logic;\r\n        RESET  : in std_logic;\r\n        ENABLE : in std_logic;\r\n        COUNT   : out std_logic_vector(3 downto 0);\r\n    );\r\nend counter;\r\n\r\narchitecture Behavioral of counter is\r\n    signal count_value: unsigned(3 downto 0);\r\nbegin\r\n\r\n    -- This is where the actual count happens\r\n    process (CLK, RESET) begin\r\n        if RESET = '1' then\r\n            count_value &lt;= (others =&gt; '0');\r\n        elsif rising_edge(CLK) then\r\n            if (enable = '1') then\r\n                if count_value &lt; MAX then\r\n                    count_value &lt;= count_value + 1;\r\n                else\r\n                     -- Back to 0 when MAX is reached\r\n                    count_value &lt;= (others =&gt; '0');\r\n                end if;\r\n            end if;\r\n        end if;\r\n    end process;\r\n\r\n    -- Output the value\r\n    COUNT &lt;= std_logic_vector(count_value);\r\nend Behavioral;\r\n<\/pre>\n<h3>Finite State Machine<\/h3>\n<p>Finite State Machines are often used in electronics as the control part of the system. They have an internal state and react to changing inputs depending on this internal state.<\/p>\n<pre class=\"brush: vhdl; title: ; notranslate\" title=\"\">\r\n--------------------------------------\r\n-- FSM that checks a button sequence.\r\n-- The sequence is left, right.\r\n-- The LED is green while the sequence is OK\r\n-- It becomes red if there is an error.\r\n--------------------------------------\r\n\r\nlibrary IEEE;\r\nuse IEEE.STD_LOGIC_1164.ALL;\r\n\r\nentity fsm is\r\n    port(\r\n        CLK          : in std_logic;\r\n        RESET        : in std_logic;\r\n        BUTTON_LEFT  : in std_logic;\r\n        BUTTON_RIGHT : in std_logic;\r\n        LED_GREEN    : out std_logic;\r\n        LED_RED      : out std_logic;\r\n    );\r\nend fsm;\r\n\r\narchitecture Behavioral of fsm is\r\n    -- Specific type with clear state names\r\n    type fsm_state is (Step1, Step2, Success, Error);\r\n    -- Current state, stored in a register\r\n    signal state     : fsm_state\r\n    -- Future state, depends on inputs and state\r\n    signal state_nxt : fsm_state;\r\nbegin\r\n\r\n    -- Current state storage, synchronous\r\n    process (CLK, RESET) begin\r\n        if RESET = '1' then\r\n            -- Initial state\r\n            state &lt;= Step1;\r\n        elsif rising_edge(CLK) then\r\n            -- Next state\r\n            state &lt;= state_nxt;\r\n    end process;\r\n\r\n    -- Future state and outputs, combinatorial\r\n    process(state, BUTTON_LEFT, BUTTON_RIGHT) begin\r\n        -- By default, the state does not change\r\n        state_nxt &lt;= state;\r\n        -- Default values of outputs\r\n        LED_GREEN &lt;= '0';\r\n        LED_RED &lt;= '0';\r\n        case state is\r\n            when Step1 =&gt;\r\n                -- Waiting for left\r\n                LED_GREEN &lt;= '1';\r\n                if BUTTON_LEFT = '1' then\r\n                    state_nxt &lt;= Step2;\r\n                elsif BUTTON_RIGHT = '1' then\r\n                    state_nxt &lt;= Error;\r\n                end if;\r\n            when Step2 =&gt;\r\n                -- Waiting for right\r\n                LED_GREEN &lt;= '1';\r\n                if BUTTON_RIGHT = '1' then\r\n                    state_nxt &lt;= Success;\r\n                elsif BUTTON_LEFT = '1' then\r\n                    state_nxt &lt;= Error;\r\n                end if;\r\n            when Success =&gt;\r\n                -- Finished, success\r\n                LED_GREEN &lt;= '1';\r\n            when Error =&gt;\r\n                -- Finished, error\r\n                LED_RED &lt;= '1';\r\n    end process;\r\nend Behavioral;\r\n<\/pre>\n<p><\/p>","protected":false},"excerpt":{"rendered":"<p>All the code in this cheat sheet is synthesizable, except in the part about simulation. Data types All signals, inputs, outputs and constants have a type in VHDL. Basic structure One file per entity, with this skeleton: Processes All processes in an entity are executed in parallel. They can describe synchronous or combinatorial circuit parts. [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":0,"parent":294,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-272","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.viesurip.fr\/en\/wp-json\/wp\/v2\/pages\/272","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.viesurip.fr\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.viesurip.fr\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.viesurip.fr\/en\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/www.viesurip.fr\/en\/wp-json\/wp\/v2\/comments?post=272"}],"version-history":[{"count":23,"href":"https:\/\/www.viesurip.fr\/en\/wp-json\/wp\/v2\/pages\/272\/revisions"}],"predecessor-version":[{"id":297,"href":"https:\/\/www.viesurip.fr\/en\/wp-json\/wp\/v2\/pages\/272\/revisions\/297"}],"up":[{"embeddable":true,"href":"https:\/\/www.viesurip.fr\/en\/wp-json\/wp\/v2\/pages\/294"}],"wp:attachment":[{"href":"https:\/\/www.viesurip.fr\/en\/wp-json\/wp\/v2\/media?parent=272"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}