<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://ift.wiki.uib.no/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Nfyku</id>
	<title>ift - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="http://ift.wiki.uib.no/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Nfyku"/>
	<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/Special:Contributions/Nfyku"/>
	<updated>2026-04-25T21:25:22Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.44.2</generator>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Bitvis_UVVM_VHDL_Verification_Component_Framework&amp;diff=2926</id>
		<title>Bitvis UVVM VHDL Verification Component Framework</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Bitvis_UVVM_VHDL_Verification_Component_Framework&amp;diff=2926"/>
		<updated>2026-03-16T12:45:25Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is heavily based on the Powerpoint-presentation found [https://github.com/UVVM/UVVM/blob/master/uvvm_util/doc/Simple_TB_step_by_step.pps here].&lt;br /&gt;
&lt;br /&gt;
Copyright 2025 UVVM&lt;br /&gt;
Licensed under the [http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 (the “License”)].&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
UVVM (Universal VHDL Verification Methodology) is a free and Open Source Methodology and Library for making very structured VHDL-based testbenches, examples and simulations scripts from the [https://github.com/UVVM/UVVM UVVM on github]. &lt;br /&gt;
&lt;br /&gt;
=== What&#039;s in the folders? ===&lt;br /&gt;
[[File:20160302215840!1.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
The download includes severals folders:&lt;br /&gt;
* bitvis_irqc - example VHDL design + testbench&lt;br /&gt;
* bitvis_uart - example VHDL design + testbench&lt;br /&gt;
* bitvis_vip_sbi - Verification IP(VIP) for simple bus interface(SBI)&lt;br /&gt;
* bitvis_vip_uart - VIP for UART TX and RX&lt;br /&gt;
* uvvm_util - UVVM utility library - sufficient for simple testbenches&lt;br /&gt;
* uvvm_vvc_framework - Framework for more advanced tutorials&lt;br /&gt;
&lt;br /&gt;
=== IRQC ===&lt;br /&gt;
[[File:irqc.png|thumb]]&lt;br /&gt;
The provided example VHDL design is a simple interrupt controller with several internal registers, a bus interface and some input and output signals.&lt;br /&gt;
&lt;br /&gt;
[[File:irqc2.png|350px]]&lt;br /&gt;
&lt;br /&gt;
== UVVM Utility Library - Testbench creation ==&lt;br /&gt;
Copy the folders bitvis_irqc, bitvis_vip_sbi and uvvm_util to another location before editing the files.&lt;br /&gt;
=== Generate TB entity with DUT instantiated ===&lt;br /&gt;
Our TB entity can in many cases be generated from several tools. Notepad++ (among other) supports plugins that enables copying an entity and pasting it as an instantiation, and also as a complete testbench template. However, we will change some of our signals so that they fit the VIP SBI BFM. The signals to and from the CPU will be converted to t_sbi_if record, which is a type that includes all the SBI signals (cs, addr, rd, wr, wdata, ready and rdata).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--Standard libraries&lt;br /&gt;
library IEEE;&lt;br /&gt;
use IEEE.std_logic_1164.all;&lt;br /&gt;
use IEEE.numeric_std.all;&lt;br /&gt;
&lt;br /&gt;
-- Library enabling control of the simulation from VHDL. Eg. std.env.stop&lt;br /&gt;
library STD;&lt;br /&gt;
use std.env.all;&lt;br /&gt;
&lt;br /&gt;
-- Obviously the UVVM library&lt;br /&gt;
library uvvm_util;&lt;br /&gt;
context uvvm_util.uvvm_util_context;&lt;br /&gt;
&lt;br /&gt;
-- We will use this library later when implementing the Bus Functional Model&lt;br /&gt;
-- Includes among much else the record type t_sbi_if and many functions&lt;br /&gt;
-- If other buses are used, you will have to change this library&lt;br /&gt;
library bitvis_vip_sbi;&lt;br /&gt;
use bitvis_vip_sbi.sbi_bfm_pkg.all;&lt;br /&gt;
&lt;br /&gt;
-- This file includes definitions of everything from registers to record types&lt;br /&gt;
use work.irqc_pif_pkg.all;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Test case entity&lt;br /&gt;
entity irqc_tb is&lt;br /&gt;
end entity;&lt;br /&gt;
&lt;br /&gt;
-- Test case architecture&lt;br /&gt;
architecture func of irqc_tb is&lt;br /&gt;
&lt;br /&gt;
  -- DSP interface and general control signals&lt;br /&gt;
  signal clk           : std_logic  := &#039;0&#039;;&lt;br /&gt;
  signal arst          : std_logic  := &#039;0&#039;;&lt;br /&gt;
  -- CPU interface&lt;br /&gt;
  -- t_sbi_if is from the verification IP SBI&lt;br /&gt;
  -- init_sbi_if_signals initialize the inputs to 0 and the outputs to Z&lt;br /&gt;
  signal sbi_if : t_sbi_if(addr(2 downto 0), wdata(7 downto 0), rdata(7 downto 0)) := init_sbi_if_signals(3, 8);&lt;br /&gt;
  &lt;br /&gt;
  -- Interrupt related signals&lt;br /&gt;
  signal irq_source    : std_logic_vector(C_NUM_SOURCES-1 downto 0) := (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
  signal irq2cpu       : std_logic := &#039;0&#039;;&lt;br /&gt;
  signal irq2cpu_ack   : std_logic := &#039;0&#039;;&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
  -----------------------------------------------------------------------------&lt;br /&gt;
  -- Instantiate DUT&lt;br /&gt;
  -----------------------------------------------------------------------------&lt;br /&gt;
  i_irqc: entity work.irqc&lt;br /&gt;
    port map (&lt;br /&gt;
    -- DSP interface and general control signals&lt;br /&gt;
        clk             =&amp;gt; clk,&lt;br /&gt;
        arst            =&amp;gt; arst,&lt;br /&gt;
    -- CPU interface&lt;br /&gt;
        cs              =&amp;gt; sbi_if.cs,             -- NOTICE THE SIGNALS ARE NOW SBI_IF&lt;br /&gt;
        addr            =&amp;gt; sbi_if.addr,&lt;br /&gt;
        wr              =&amp;gt; sbi_if.wena,&lt;br /&gt;
        rd              =&amp;gt; sbi_if.rena,&lt;br /&gt;
        din             =&amp;gt; sbi_if.wdata,&lt;br /&gt;
        dout            =&amp;gt; sbi_if.rdata,&lt;br /&gt;
    -- Interrupt related signals&lt;br /&gt;
        irq_source      =&amp;gt; irq_source,&lt;br /&gt;
        irq2cpu         =&amp;gt; irq2cpu,&lt;br /&gt;
        irq2cpu_ack     =&amp;gt; irq2cpu_ack&lt;br /&gt;
        );&lt;br /&gt;
 &lt;br /&gt;
end func;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support process for clock generation ===&lt;br /&gt;
We now have to add a support process that controls the clock. This has to allow enabling/disabling from the test sequencer. We add the following before &amp;quot;begin&amp;quot; in our architecture:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-- Added for clock generation&lt;br /&gt;
  signal clock_ena  : boolean := false;&lt;br /&gt;
&lt;br /&gt;
  constant C_CLK_PERIOD : time := 10 ns;&lt;br /&gt;
  &lt;br /&gt;
  procedure clock_gen(&lt;br /&gt;
    signal   clock_signal  : inout std_logic;&lt;br /&gt;
    signal   clock_ena     : in    boolean;&lt;br /&gt;
    constant clock_period  : in    time&lt;br /&gt;
  ) is&lt;br /&gt;
    variable v_first_half_clk_period : time := C_CLK_PERIOD / 2;&lt;br /&gt;
  begin&lt;br /&gt;
    loop&lt;br /&gt;
      if not clock_ena then&lt;br /&gt;
        wait until clock_ena;&lt;br /&gt;
      end if;&lt;br /&gt;
      wait for v_first_half_clk_period;&lt;br /&gt;
      clock_signal &amp;lt;= not clock_signal;&lt;br /&gt;
      wait for (clock_period - v_first_half_clk_period);&lt;br /&gt;
      clock_signal &amp;lt;= not clock_signal;&lt;br /&gt;
    end loop;&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our clock can now be activated from the test sequencer (this will be added in the next step):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-- After begin in the architecture&lt;br /&gt;
clock_gen(clk, clock_ena, C_CLK_PERIOD);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Inside the test sequencer process&lt;br /&gt;
clock_ena &amp;lt;= true;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add test sequencer process ===&lt;br /&gt;
The next step is to add the test sequencer process. This process controls everything from initialization to termination of the simulation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 -- Set upt clock generator&lt;br /&gt;
  clock_gen(clk, clock_ena, C_CLK_PERIOD);      &lt;br /&gt;
 &lt;br /&gt;
  ------------------------------------------------&lt;br /&gt;
  -- PROCESS: p_main&lt;br /&gt;
  ------------------------------------------------&lt;br /&gt;
  p_main : process&lt;br /&gt;
  -- The scope tells you where log messages originates - C_SCOPE tells us they originate from the default test sequencer scope&lt;br /&gt;
  constant C_SCOPE     : string  := C_TB_SCOPE_DEFAULT;&lt;br /&gt;
  -- This is where we will add some procedures later to simplify the tests&lt;br /&gt;
  &lt;br /&gt;
  begin&lt;br /&gt;
  &lt;br /&gt;
  --Print the configuration to the log&lt;br /&gt;
  report_global_ctrl(VOID);&lt;br /&gt;
  report_msg_id_panel(VOID);&lt;br /&gt;
  &lt;br /&gt;
  enable_log_msg(ALL_MESSAGES);&lt;br /&gt;
  --disable_log_msg&lt;br /&gt;
  --enable_log_msg(ID_LOG_HDR);&lt;br /&gt;
  &lt;br /&gt;
  log(ID_LOG_HDR, &amp;quot;Start Simulation of TB for IRQC&amp;quot;, C_SCOPE);&lt;br /&gt;
  ------------------------------------------------------------&lt;br /&gt;
  clock_ena &amp;lt;= true;   -- to start clock generator&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  ------------------------------------------------------------&lt;br /&gt;
  -- End the simulation&lt;br /&gt;
  wait for 1000 ns;                       -- to allow some time for completion&lt;br /&gt;
  report_alert_counters(FINAL);            -- Report final counters and print conclusion for simulation (Success/Fail)&lt;br /&gt;
  log(ID_LOG_HDR, &amp;quot;SIMULATION COMPLETED&amp;quot;, C_SCOPE);&lt;br /&gt;
  &lt;br /&gt;
  --Finish the simulation&lt;br /&gt;
  std.env.stop;&lt;br /&gt;
  wait; -- to stop completely&lt;br /&gt;
  end process p_main;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Simulation==&lt;br /&gt;
We now have the skeleton of the testbench, which we will develop further. But now, let&#039;s see if everything works. UVVM includes simulation scripts for the IRQC example that compiles everything we need, from the source files of the VHDL design, to the testbench (if you called the file irqc_tb.vhd and placed it in the tb-folder) and the SBI BFM and the UVVM library. Open up QuestaSim/ModelSim.&lt;br /&gt;
Change directory to the script folder (where you have copied the UVVM files), for example in phys321/bitviswiki.....:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ~/phys321/bitviswiki/bitvis_irqc/script&lt;br /&gt;
do compile_and_sim_all.do&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will present our result in the transcript windows, but also write _Log.txt file which includes all the information we have asked for. We see that we get the results from the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
report_global_ctrl(VOID);&lt;br /&gt;
report_msg_id_panel(VOID);&lt;br /&gt;
enable_log_msg(ALL_MESSAGES);&lt;br /&gt;
log(ID_LOG_HDR, &amp;quot;Start Simulation of TB for IRQC&amp;quot;, C_SCOPE);&lt;br /&gt;
report_alert_counters(FINAL);&lt;br /&gt;
log(ID_LOG_HDR, &amp;quot;SIMULATION COMPLETED&amp;quot;, C_SCOPE);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Commenting these out will result in an empty log.&lt;br /&gt;
&lt;br /&gt;
== Verbosity control ==&lt;br /&gt;
We want to able to control the amount of information in our logs, and the framework enables us to prioritize messages based on ID. This makes it easy to turn on or off the information we want.&lt;br /&gt;
To turn on a specific ID&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
enable_log_msg(IDNAME);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Turn off:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disable_log_msg(IDNAME);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For writing a message to a certain log ID:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
log(IDNAME, &amp;quot;MESSAGE HERE&amp;quot;, C_SCOPE);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Remember that C_SCOPE just tells us that the message originated from the default scope and will look like &amp;quot;TB seq.&amp;quot; in the log file.&lt;br /&gt;
&lt;br /&gt;
Exampled IDs:&lt;br /&gt;
* ID_LOG_HDR,           -- ONLY allowed in test sequencer, Log section headers&lt;br /&gt;
* ID_SEQUENCER,         -- ONLY allowed in test sequencer, Normal log (not log headers)&lt;br /&gt;
* ID_BFM,               -- Used inside a BFM (to log BFM access)&lt;br /&gt;
* ID_CLOCK_GEN,         -- Used for logging when clock generators are enabled or disabled&lt;br /&gt;
* ALL_MESSAGES          -- Applies to ALL message ID apart from ID_NEVER&lt;br /&gt;
&lt;br /&gt;
You&#039;ll find all the different ID&#039;s in the UVVM Utility Library Quick Reference or defined in uvvm_util/adaptions_pkg.vhd. This also where C_TB_SCOPE_DEFAULT is defined.&lt;br /&gt;
&lt;br /&gt;
== Implement first tests ==&lt;br /&gt;
[[File:tb.png|thumb|upright=0.35]]&lt;br /&gt;
We want to check and verify that our testbench is up and running and to verify our first tests of the DUT. This means that we have to able to set all our signals passive, apply a reset signal and then check the default outputs of the DUT.&lt;br /&gt;
&lt;br /&gt;
Instead of setting all our signals passive one-by-one in our test sequencer we declare a procedure in our p_main process(this is done before begin):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
procedure set_inputs_passive(&lt;br /&gt;
      dummy   : t_void) is           --dummy variable is included only to allow calling the procedure with parenthesis for readability&lt;br /&gt;
    begin&lt;br /&gt;
      sbi_if.cs           &amp;lt;= &#039;0&#039;;&lt;br /&gt;
      sbi_if.addr         &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
      sbi_if.wena         &amp;lt;= &#039;0&#039;;&lt;br /&gt;
      sbi_if.rena         &amp;lt;= &#039;0&#039;;&lt;br /&gt;
      sbi_if.wdata          &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
      irq_source   &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
      irq2cpu_ack  &amp;lt;= &#039;0&#039;;&lt;br /&gt;
      log(ID_SEQUENCER_SUB, &amp;quot;All inputs set passive&amp;quot;, C_SCOPE);&lt;br /&gt;
    end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the procedure declaration also includes a dummy variable parameter. This means that we will be able to call the procedure with the more readable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set_inputs_passive(VOID);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rather than:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set_inputs_passive;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
which is more ambigious.&lt;br /&gt;
&lt;br /&gt;
We may also would like to send pulses on different signals, f.ex. sending a pulse on our reset to see if it behaves like intended. We therefore can include a pulse procedure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
procedure pulse(&lt;br /&gt;
      signal   target        : inout  std_logic_vector;&lt;br /&gt;
      constant pulse_value   : in     std_logic_vector;&lt;br /&gt;
      signal   clock_signal  : in     std_logic;&lt;br /&gt;
      constant num_periods   : in     natural;&lt;br /&gt;
      constant msg           : in     string) is&lt;br /&gt;
    begin&lt;br /&gt;
      if num_periods &amp;gt; 0 then&lt;br /&gt;
        wait until falling_edge(clock_signal);&lt;br /&gt;
        target &amp;lt;= pulse_value;&lt;br /&gt;
        for i in 1 to num_periods loop&lt;br /&gt;
          wait until falling_edge(clock_signal);&lt;br /&gt;
        end loop;&lt;br /&gt;
      else&lt;br /&gt;
        target &amp;lt;= pulse_value;&lt;br /&gt;
        wait for 0 ns;  -- Delta cycle only&lt;br /&gt;
      end if;&lt;br /&gt;
      target(target&#039;range) &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
      log(ID_SEQUENCER_SUB, &amp;quot;Pulsed to &amp;quot; &amp;amp; to_string(pulse_value, HEX, AS_IS, INCL_RADIX) &amp;amp; &amp;quot;. &amp;quot; &amp;amp; msg, C_SCOPE);&lt;br /&gt;
    end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example the test sequencer is required to inform the procedure of what value the pulse is to take. The call to the procedure would take the following form:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
pulse(arst, &#039;Z&#039;, clk, 10, &amp;quot;Log message - Im pulsing the value &#039;Z&#039;&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
But a more specific overload can be created where pulse always takes value &#039;1&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
procedure pulse(&lt;br /&gt;
      signal   target          : inout std_logic;&lt;br /&gt;
      signal   clock_signal    : in    std_logic;&lt;br /&gt;
      constant num_periods     : in    natural;&lt;br /&gt;
      constant msg             : in    string&lt;br /&gt;
    ) is&lt;br /&gt;
    begin&lt;br /&gt;
      if num_periods &amp;gt; 0 then&lt;br /&gt;
        wait until falling_edge(clock_signal);&lt;br /&gt;
        target  &amp;lt;= &#039;1&#039;;&lt;br /&gt;
        for i in 1 to num_periods loop&lt;br /&gt;
          wait until falling_edge(clock_signal);&lt;br /&gt;
        end loop;&lt;br /&gt;
      else&lt;br /&gt;
        target  &amp;lt;= &#039;1&#039;;&lt;br /&gt;
        wait for 0 ns;  -- Delta cycle only&lt;br /&gt;
      end if;&lt;br /&gt;
      target  &amp;lt;= &#039;0&#039;;&lt;br /&gt;
      log(ID_SEQUENCER_SUB, msg, C_SCOPE);&lt;br /&gt;
    end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These procedures can now be called directly from our test sequence:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set_inputs_passive(VOID);&lt;br /&gt;
pulse(arst, clk, 10, &amp;quot;pulsed reset-signal - active for 10T&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To check signal values we can use the built-in check function check_value():&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
check_value(irq2cpu, &#039;X&#039;, ERROR, &amp;quot;Interrupt to CPU must be default inactive&amp;quot;, C_SCOPE);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above call checks if the signal irq2cpu is &#039;X&#039;, and obviously fail if everything works correctly and gives the following message:&lt;br /&gt;
&lt;br /&gt;
[[File:error.png|700px]]&lt;br /&gt;
&lt;br /&gt;
If we want we can change the number of errors logged before the simulation stops:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set_alert_stop_limit(ERROR, 3);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We now have all the tools needed for the first tests in our sequencer:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set_inputs_passive(VOID);&lt;br /&gt;
pulse(arst, clk, 10, &amp;quot;Pulsed reset-signal - active for 10T&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
check_value(C_NUM_SOURCES &amp;gt; 0, FAILURE, &amp;quot;Must be at least 1 interrupt source&amp;quot;, C_SCOPE);&lt;br /&gt;
check_value(C_NUM_SOURCES &amp;lt;= 8, TB_WARNING, &amp;quot;This TB is only checking IRQC with up to 8 interrupt sources&amp;quot;, C_SCOPE);&lt;br /&gt;
  &lt;br /&gt;
log(ID_LOG_HDR, &amp;quot;Check defaults on output ports&amp;quot;, C_SCOPE);&lt;br /&gt;
------------------------------------------------------------&lt;br /&gt;
check_value(irq2cpu, &#039;0&#039;, ERROR, &amp;quot;Interrupt to CPU must be default inactive&amp;quot;, C_SCOPE);&lt;br /&gt;
check_value(sbi_if.rdata, x&amp;quot;00&amp;quot;, ERROR, &amp;quot;Register data bus output must be default passive&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will give us the following log:&lt;br /&gt;
&lt;br /&gt;
[[File:sim.png|800px]]&lt;br /&gt;
&lt;br /&gt;
This information may only interesting initially and for debug, and can be turned on or off by use of ID.&lt;br /&gt;
&lt;br /&gt;
== Subprograms ==&lt;br /&gt;
Some of our testbench code will be repeated several times and the testbench may therefore benefit from creating several subprograms. Obvious examples for our IRQC is:&lt;br /&gt;
- Register access&lt;br /&gt;
- Signal checkers&lt;br /&gt;
- Interrupt source pulsing?&lt;br /&gt;
- Interrupt acknowledge pulsing?&lt;br /&gt;
- (Report/log method)&lt;br /&gt;
- (Alert-handling)&lt;br /&gt;
- (reset, set_passive, ...)&lt;br /&gt;
&lt;br /&gt;
We&#039;ve already created and declared set_passive and pulse procedures, but we could f.ex create overloads for UVVM procedures:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    -- Log overloads for simplification&lt;br /&gt;
    procedure log(&lt;br /&gt;
      msg   : string) is&lt;br /&gt;
    begin&lt;br /&gt;
      log(ID_SEQUENCER, msg, C_SCOPE);&lt;br /&gt;
    end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This exact function is already overloaded in the UVVM packages, so including this in our testbench would produce compilation errors. So, let&#039;s not include it, but view it as an example of how it&#039;s done.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s say that it is probable that we&#039;ll want to change the number of interrupt sources that the controller can handle. We will then want to able to easily change vectors to the appropriate size. One way is to declare procedures that can trim and fit vectors. This way we can simply change a constant to change the number of sources.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  subtype t_irq_source is std_logic_vector(C_NUM_SOURCES-1 downto 0);&lt;br /&gt;
&lt;br /&gt;
  -- Trim (cut) a given vector to fit the number of irq sources (i.e. pot. reduce width)&lt;br /&gt;
  function trim(&lt;br /&gt;
    constant source   : std_logic_vector;&lt;br /&gt;
    constant num_bits : positive := C_NUM_SOURCES)&lt;br /&gt;
  return t_irq_source is&lt;br /&gt;
    variable v_result : std_logic_vector(source&#039;length-1 downto 0) := source;&lt;br /&gt;
  begin&lt;br /&gt;
    return v_result(num_bits-1 downto 0);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  -- Fit a given vector to the number of irq sources by masking with zeros above irq width&lt;br /&gt;
  function fit(&lt;br /&gt;
    constant source   : std_logic_vector;&lt;br /&gt;
    constant num_bits : positive := C_NUM_SOURCES)&lt;br /&gt;
  return std_logic_vector is&lt;br /&gt;
    variable v_result : std_logic_vector(source&#039;length-1 downto 0) := (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
    variable v_source : std_logic_vector(source&#039;length-1 downto 0) := source;&lt;br /&gt;
  begin&lt;br /&gt;
    v_result(num_bits-1 downto 0) := v_source(num_bits-1 downto 0);&lt;br /&gt;
    return v_result;&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All IRQC-dedicated subprograms should be declared locally, but more common (f.ex bus-specific) should be declared in common package that can be shared with other.&lt;br /&gt;
&lt;br /&gt;
== Register access ==&lt;br /&gt;
To access the IRQC&#039;s registers we need to go through the actual process of writing and reading data from them. Fortunately, Bitvis have already taken the responsibility of writing the BFM for the SBI. This doesn&#039;t mean that we doesn&#039;t have to understand what&#039;s going on, since we&#039;ll have to write our own BFM&#039;s for other buses that we use(Avalon, AXI, etc). &#039;&#039;&#039;January 2017 Bitvis announced that they released VVC for Avalon-MM and AXI4-lite.&#039;&#039;&#039; So we should investigate the BFM procedures. We want to check register values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
procedure sbi_check (&lt;br /&gt;
    constant addr_value   : in    unsigned;&lt;br /&gt;
    constant data_exp     : in    std_logic_vector;&lt;br /&gt;
    constant msg          : in    string;&lt;br /&gt;
    signal   clk          : in    std_logic;&lt;br /&gt;
    signal   cs           : inout std_logic;&lt;br /&gt;
    signal   addr         : inout unsigned;&lt;br /&gt;
    signal   rd           : inout std_logic;&lt;br /&gt;
    signal   wr           : inout std_logic;&lt;br /&gt;
    signal   ready        : in    std_logic;&lt;br /&gt;
    signal   rdata        : in    std_logic_vector;&lt;br /&gt;
    constant alert_level  : in    t_alert_level     := error;&lt;br /&gt;
    constant scope        : in    string            := C_SCOPE;&lt;br /&gt;
    constant msg_id_panel : in    t_msg_id_panel    := shared_msg_id_panel;&lt;br /&gt;
    constant config       : in    t_sbi_bfm_config  := C_SBI_BFM_CONFIG_DEFAULT&lt;br /&gt;
  ) is&lt;br /&gt;
    constant proc_name    : string :=  &amp;quot;sbi_check&amp;quot;;&lt;br /&gt;
    constant proc_call    : string :=  &amp;quot;sbi_check(A:&amp;quot; &amp;amp; to_string(addr_value, HEX, AS_IS, INCL_RADIX) &amp;amp;&lt;br /&gt;
                                       &amp;quot;, &amp;quot;  &amp;amp; to_string(data_exp, HEX, AS_IS, INCL_RADIX) &amp;amp; &amp;quot;)&amp;quot;;&lt;br /&gt;
    -- Normalize to the DUT addr/data widths&lt;br /&gt;
    variable v_normalised_addr    : unsigned(addr&#039;length-1 downto 0) :=&lt;br /&gt;
      normalize_and_check(addr_value, addr, ALLOW_WIDER_NARROWER, &amp;quot;addr_value&amp;quot;, &amp;quot;sbi_core_in.addr&amp;quot;, msg);&lt;br /&gt;
    -- Helper variables&lt;br /&gt;
    variable v_data_value         : std_logic_vector(rdata&#039;length - 1 downto 0);&lt;br /&gt;
    variable v_check_ok           : boolean;&lt;br /&gt;
    variable v_clk_cycles_waited  : natural := 0;&lt;br /&gt;
  begin&lt;br /&gt;
    sbi_read(addr_value, v_data_value, msg, clk, cs, addr, rd, wr, ready, rdata, scope, msg_id_panel, config, proc_name);&lt;br /&gt;
&lt;br /&gt;
    -- Compare values, but ignore any leading zero&#039;s if widths are different.&lt;br /&gt;
    -- Use ID_NEVER so that check_value method does not log when check is OK,&lt;br /&gt;
    -- log it here instead.&lt;br /&gt;
    v_check_ok := check_value(v_data_value, data_exp, alert_level, msg, scope, HEX_BIN_IF_INVALID, SKIP_LEADING_0, ID_NEVER, msg_id_panel, proc_call);&lt;br /&gt;
    if v_check_ok then&lt;br /&gt;
      log(config.id_for_bfm, proc_call &amp;amp; &amp;quot;=&amp;gt; OK, read data = &amp;quot; &amp;amp; to_string(v_data_value, HEX, SKIP_LEADING_0, INCL_RADIX) &amp;amp; &amp;quot;. &amp;quot; &amp;amp; msg, scope, msg_id_panel);&lt;br /&gt;
    end if;&lt;br /&gt;
  end procedure;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We see that sbi_check() calls sbi_read() before it checks if the read value is the expected value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
procedure sbi_read (&lt;br /&gt;
    constant addr_value    : in     unsigned;&lt;br /&gt;
    variable data_value    : out    std_logic_vector;&lt;br /&gt;
    constant msg           : in     string;&lt;br /&gt;
    signal   clk           : in     std_logic;&lt;br /&gt;
    signal   cs            : inout  std_logic;&lt;br /&gt;
    signal   addr          : inout  unsigned;&lt;br /&gt;
    signal   rd            : inout  std_logic;&lt;br /&gt;
    signal   wr            : inout  std_logic;&lt;br /&gt;
    signal   ready         : in     std_logic;&lt;br /&gt;
    signal   rdata         : in     std_logic_vector;&lt;br /&gt;
    constant scope         : in     string            := C_SCOPE;&lt;br /&gt;
    constant msg_id_panel  : in     t_msg_id_panel    := shared_msg_id_panel;&lt;br /&gt;
    constant config        : in     t_sbi_bfm_config  := C_SBI_BFM_CONFIG_DEFAULT;&lt;br /&gt;
    constant proc_name     : in     string            := &amp;quot;sbi_read&amp;quot;  -- overwrite if called from other procedure like sbi_check&lt;br /&gt;
  ) is&lt;br /&gt;
    constant proc_call            : string := &amp;quot;sbi_read(A:&amp;quot; &amp;amp; to_string(addr_value, HEX, AS_IS, INCL_RADIX) &amp;amp; &amp;quot;)&amp;quot;;&lt;br /&gt;
    -- Normalize to the DUT addr/data widths&lt;br /&gt;
    variable v_normalised_addr    : unsigned(addr&#039;length-1 downto 0) :=&lt;br /&gt;
        normalize_and_check(addr_value, addr, ALLOW_WIDER_NARROWER, &amp;quot;addr_value&amp;quot;, &amp;quot;sbi_core_in.addr&amp;quot;, msg);&lt;br /&gt;
    variable v_data_value         : std_logic_vector(data_value&#039;range);&lt;br /&gt;
    variable v_clk_cycles_waited  : natural := 0;&lt;br /&gt;
  begin&lt;br /&gt;
    wait_until_given_time_after_rising_edge(clk, config.clock_period/4);&lt;br /&gt;
    cs   &amp;lt;= &#039;1&#039;;&lt;br /&gt;
    wr   &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    rd   &amp;lt;= &#039;1&#039;;&lt;br /&gt;
    addr &amp;lt;= v_normalised_addr;&lt;br /&gt;
    wait for config.clock_period;&lt;br /&gt;
    while (config.use_ready_signal and ready = &#039;0&#039;) loop&lt;br /&gt;
      if v_clk_cycles_waited = 0 then&lt;br /&gt;
        log(config.id_for_bfm_wait, proc_call &amp;amp; &amp;quot; waiting for response (sbi ready=0)&amp;quot; &amp;amp; msg, scope, msg_id_panel);&lt;br /&gt;
      end if;&lt;br /&gt;
      wait for config.clock_period;&lt;br /&gt;
      v_clk_cycles_waited := v_clk_cycles_waited + 1;&lt;br /&gt;
      check_value(v_clk_cycles_waited &amp;lt;= config.max_wait_cycles, config.max_wait_cycles_severity,&lt;br /&gt;
                  &amp;quot;: Timeout while waiting for sbi ready&amp;quot;, scope, ID_NEVER, msg_id_panel, proc_call);&lt;br /&gt;
    end loop;&lt;br /&gt;
&lt;br /&gt;
    cs  &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    rd  &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    v_data_value  := rdata;&lt;br /&gt;
    data_value    := v_data_value;&lt;br /&gt;
    if proc_name = &amp;quot;sbi_read&amp;quot; then&lt;br /&gt;
      log(config.id_for_bfm, proc_call &amp;amp; &amp;quot;=&amp;gt; &amp;quot; &amp;amp; to_string(v_data_value, HEX, SKIP_LEADING_0, INCL_RADIX) &amp;amp; &amp;quot;. &amp;quot; &amp;amp; msg, scope, msg_id_panel);&lt;br /&gt;
    else&lt;br /&gt;
      -- Log will be handled by calling procedure (e.g. sbi_check)&lt;br /&gt;
    end if;&lt;br /&gt;
  end procedure;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We don&#039;t want to (and probably shouldnt) call the sbi_check and providing all the parameters each time. Some of this can be solved by the overloads with more standard parameters, and with our own check procedures declared locally in our testbench:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    procedure check(&lt;br /&gt;
      constant addr_value   : in natural;&lt;br /&gt;
      constant data_exp     : in std_logic_vector;&lt;br /&gt;
      constant alert_level  : in t_alert_level;&lt;br /&gt;
      constant msg          : in string) is&lt;br /&gt;
    begin&lt;br /&gt;
      sbi_check(to_unsigned(addr_value, sbi_if.addr&#039;length), data_exp, msg,&lt;br /&gt;
            clk, sbi_if, alert_level, C_SCOPE);&lt;br /&gt;
    end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The write procedure is also very handy and should be understood:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  procedure sbi_write (&lt;br /&gt;
    constant addr_value   : in    unsigned;&lt;br /&gt;
    constant data_value   : in    std_logic_vector;&lt;br /&gt;
    constant msg          : in    string;&lt;br /&gt;
    signal   clk          : in    std_logic;&lt;br /&gt;
    signal   cs           : inout std_logic;&lt;br /&gt;
    signal   addr         : inout unsigned;&lt;br /&gt;
    signal   rd           : inout std_logic;&lt;br /&gt;
    signal   wr           : inout std_logic;&lt;br /&gt;
    signal   ready        : in    std_logic;&lt;br /&gt;
    signal   wdata        : inout std_logic_vector;&lt;br /&gt;
    constant scope        : in    string            := C_SCOPE;&lt;br /&gt;
    constant msg_id_panel : in    t_msg_id_panel    := shared_msg_id_panel;&lt;br /&gt;
    constant config       : in    t_sbi_bfm_config  := C_SBI_BFM_CONFIG_DEFAULT&lt;br /&gt;
  ) is&lt;br /&gt;
    constant proc_name  : string :=  &amp;quot;sbi_write&amp;quot;;&lt;br /&gt;
    constant proc_call  : string :=  &amp;quot;sbi_write(A:&amp;quot; &amp;amp; to_string(addr_value, HEX, AS_IS, INCL_RADIX) &amp;amp;&lt;br /&gt;
                                     &amp;quot;, &amp;quot; &amp;amp; to_string(data_value, HEX, AS_IS, INCL_RADIX) &amp;amp; &amp;quot;)&amp;quot;;&lt;br /&gt;
    -- Normalise to the DUT addr/data widths&lt;br /&gt;
    variable v_normalised_addr    : unsigned(addr&#039;length-1 downto 0) :=&lt;br /&gt;
        normalize_and_check(addr_value, addr, ALLOW_WIDER_NARROWER, &amp;quot;addr_value&amp;quot;, &amp;quot;sbi_core_in.addr&amp;quot;, msg);&lt;br /&gt;
    variable v_normalised_data    : std_logic_vector(wdata&#039;length-1 downto 0) :=&lt;br /&gt;
        normalize_and_check(data_value, wdata, ALLOW_NARROWER, &amp;quot;data_value&amp;quot;, &amp;quot;sbi_core_in.wdata&amp;quot;, msg);&lt;br /&gt;
    variable v_clk_cycles_waited  : natural := 0;&lt;br /&gt;
  begin&lt;br /&gt;
    wait_until_given_time_after_rising_edge(clk, config.clock_period/4);&lt;br /&gt;
    cs    &amp;lt;= &#039;1&#039;;&lt;br /&gt;
    wr    &amp;lt;= &#039;1&#039;;&lt;br /&gt;
    rd    &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    addr  &amp;lt;= v_normalised_addr;&lt;br /&gt;
    wdata &amp;lt;= v_normalised_data;&lt;br /&gt;
&lt;br /&gt;
    wait for config.clock_period;&lt;br /&gt;
    while (config.use_ready_signal and ready = &#039;0&#039;) loop&lt;br /&gt;
      if v_clk_cycles_waited = 0 then&lt;br /&gt;
        log(config.id_for_bfm_wait, proc_call &amp;amp; &amp;quot; waiting for response (sbi ready=0)&amp;quot; &amp;amp; msg, scope, msg_id_panel);&lt;br /&gt;
      end if;&lt;br /&gt;
      wait for config.clock_period;&lt;br /&gt;
      v_clk_cycles_waited := v_clk_cycles_waited + 1;&lt;br /&gt;
      check_value(v_clk_cycles_waited &amp;lt;= config.max_wait_cycles, config.max_wait_cycles_severity,&lt;br /&gt;
                  &amp;quot;: Timeout while waiting for sbi ready&amp;quot;, scope, ID_NEVER, msg_id_panel, proc_call);&lt;br /&gt;
    end loop;&lt;br /&gt;
&lt;br /&gt;
    cs  &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    wr  &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    log(config.id_for_bfm, proc_call &amp;amp; &amp;quot; completed. &amp;quot; &amp;amp; msg, scope, msg_id_panel);&lt;br /&gt;
  end procedure;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We will create a local overload of this too:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
procedure write(&lt;br /&gt;
      constant addr_value   : in natural;&lt;br /&gt;
      constant data_value   : in std_logic_vector;&lt;br /&gt;
      constant msg          : in string) is&lt;br /&gt;
    begin&lt;br /&gt;
      sbi_write(to_unsigned(addr_value, sbi_if.addr&#039;length), data_value, msg,&lt;br /&gt;
            clk, sbi_if, C_SCOPE);&lt;br /&gt;
    end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We also need to set the sbi_if.ready signal high for this to work:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clock_generator(clk, clock_ena, C_CLK_PERIOD, &amp;quot;IRQC TB clock&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
-- Insert this here by the clock generator&lt;br /&gt;
sbi_if.ready &amp;lt;= &#039;1&#039;; -- always ready in the same clock cycle.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All this enables us to handle transactions at a high level. See UVVM documentation for how to write your own BFM and what it should include(sanity checks, etc).&lt;br /&gt;
&lt;br /&gt;
[[File:bfm.png|550px]]&lt;br /&gt;
&lt;br /&gt;
== Checking register write and read ==&lt;br /&gt;
Now we&#039;re enabled to write to and read from the registers. The register addresses are defined in the IRQC package file irqc_pif_bkg.vhd. Notice that we also use the previously declared overloaded version of log() and fit().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
log(ID_LOG_HDR, &amp;quot;Check register defaults and access (write + read)&amp;quot;, C_SCOPE);&lt;br /&gt;
    ------------------------------------------------------------&lt;br /&gt;
    log(&amp;quot;\nChecking Register defaults&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, x&amp;quot;00&amp;quot;, ERROR, &amp;quot;IRR default&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IER, x&amp;quot;00&amp;quot;, ERROR, &amp;quot;IER default&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IPR, x&amp;quot;00&amp;quot;, ERROR, &amp;quot;IPR default&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRQ2CPU_ALLOWED, x&amp;quot;00&amp;quot;, ERROR, &amp;quot;IRQ2CPU_ALLOWED default&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    log(&amp;quot;\nChecking Register Write/Read&amp;quot;);&lt;br /&gt;
    write(C_ADDR_IER, fit(x&amp;quot;55&amp;quot;), &amp;quot;IER&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IER, fit(x&amp;quot;55&amp;quot;), ERROR, &amp;quot;IER pure readback&amp;quot;);&lt;br /&gt;
    write(C_ADDR_IER, fit(x&amp;quot;AA&amp;quot;), &amp;quot;IER&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IER, fit(x&amp;quot;AA&amp;quot;), ERROR, &amp;quot;IER pure readback&amp;quot;);&lt;br /&gt;
    write(C_ADDR_IER, fit(x&amp;quot;00&amp;quot;), &amp;quot;IER&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IER, fit(x&amp;quot;00&amp;quot;), ERROR, &amp;quot;IER pure readback&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This check will give us a nice log if everything turns out ok:&lt;br /&gt;
&lt;br /&gt;
[[File:sim2.png|700px]]&lt;br /&gt;
&lt;br /&gt;
However, if there&#039;s an error:&lt;br /&gt;
&lt;br /&gt;
[[File:error2.png|700px]]&lt;br /&gt;
&lt;br /&gt;
== Further tests ==&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve tested register read/write, we should test the trigger/clear mechanism. No further adding of procedures are necessary.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    log(ID_LOG_HDR, &amp;quot;Check register trigger/clear mechanism&amp;quot;, C_SCOPE);&lt;br /&gt;
    ------------------------------------------------------------&lt;br /&gt;
    write(C_ADDR_ITR, fit(x&amp;quot;AA&amp;quot;), &amp;quot;ITR : Set interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;AA&amp;quot;), ERROR, &amp;quot;IRR&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ITR, fit(x&amp;quot;55&amp;quot;), &amp;quot;ITR : Set more interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;FF&amp;quot;), ERROR, &amp;quot;IRR&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ICR, fit(x&amp;quot;71&amp;quot;), &amp;quot;ICR : Clear interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;8E&amp;quot;), ERROR, &amp;quot;IRR&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ICR, fit(x&amp;quot;85&amp;quot;), &amp;quot;ICR : Clear interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;0A&amp;quot;), ERROR, &amp;quot;IRR&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ITR, fit(x&amp;quot;55&amp;quot;), &amp;quot;ITR : Set more interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;5F&amp;quot;), ERROR, &amp;quot;IRR&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ICR, fit(x&amp;quot;5F&amp;quot;), &amp;quot;ICR : Clear interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;00&amp;quot;), ERROR, &amp;quot;IRR&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The UVVM Utility Library provides all necessary functions and procedures to do further tests. F.ex. we should send pulses on the irq_source signal to check if the design behaves correctly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
log(ID_LOG_HDR, &amp;quot;Check interrupt sources, IER, IPR and irq2cpu&amp;quot;, C_SCOPE);&lt;br /&gt;
    ------------------------------------------------------------&lt;br /&gt;
    log(&amp;quot;\nChecking interrupts and IRR&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ICR, fit(x&amp;quot;FF&amp;quot;), &amp;quot;ICR : Clear all interrupts&amp;quot;);&lt;br /&gt;
    pulse(irq_source, trim(x&amp;quot;AA&amp;quot;), clk, 1, &amp;quot;Pulse irq_source 1T&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;AA&amp;quot;), ERROR, &amp;quot;IRR after irq pulses&amp;quot;);&lt;br /&gt;
    pulse(irq_source, trim(x&amp;quot;01&amp;quot;), clk, 1, &amp;quot;Add more interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;AB&amp;quot;), ERROR, &amp;quot;IRR after irq pulses&amp;quot;);&lt;br /&gt;
    pulse(irq_source, trim(x&amp;quot;A1&amp;quot;), clk, 1, &amp;quot;Repeat same interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;AB&amp;quot;), ERROR, &amp;quot;IRR after irq pulses&amp;quot;);&lt;br /&gt;
    pulse(irq_source, trim(x&amp;quot;54&amp;quot;), clk, 1, &amp;quot;Add remaining interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;FF&amp;quot;), ERROR, &amp;quot;IRR after irq pulses&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ICR, fit(x&amp;quot;AA&amp;quot;), &amp;quot;ICR : Clear half the interrupts&amp;quot;);&lt;br /&gt;
    pulse(irq_source, trim(x&amp;quot;A0&amp;quot;), clk, 1, &amp;quot;Add more interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;F5&amp;quot;), ERROR, &amp;quot;IRR after irq pulses&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ICR, fit(x&amp;quot;FF&amp;quot;), &amp;quot;ICR : Clear all interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;00&amp;quot;), ERROR, &amp;quot;IRR after clearing all&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Check stable ===&lt;br /&gt;
Another test provided by UVVM is check_stable(). This function enables us to test if a signal is holding the same value for a minimum provided time. We must declare a variable that holds the time from which we want to test if the signal is stable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v_time_stamp := now;  -- time from which irq2cpu should be stable off until triggered&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Later we&#039;re now able to test if the signal has been holding the same value the whole period:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
check_stable(irq2cpu, (now - v_time_stamp), ERROR, &amp;quot;No spikes allowed on irq2cpu&amp;quot;, C_SCOPE);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remember to declare the variable in the process:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
variable v_time_stamp   : time := 0 ns;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Await value ===&lt;br /&gt;
To check if a signal gets the expected value within a specified time value we use await_vale(). The test below throws an error if irq2cpu doesn&#039;t obtain the value &#039;1&#039; within 0 ns(!). Therefore expected immediately:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
await_value(irq2cpu, &#039;1&#039;, 0 ns, C_CLK_PERIOD, ERROR, &amp;quot;Interrupt expected immediately&amp;quot;, C_SCOPE);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other useful functions ===&lt;br /&gt;
&lt;br /&gt;
Check the UVVM Utility Library Quick Reference for syntax details.&lt;br /&gt;
&lt;br /&gt;
==== await_change() ====&lt;br /&gt;
Expects and waits for a change on the given signal, inside a given time window. &lt;br /&gt;
&lt;br /&gt;
==== check_value_in_range() ====&lt;br /&gt;
Throws an error of the signal value is outside the specified minimum and maximum values.&lt;br /&gt;
&lt;br /&gt;
== UVVM VVC ==&lt;br /&gt;
Guide coming....&lt;br /&gt;
&lt;br /&gt;
== UVVM LICENCE AGREEMENT ==&lt;br /&gt;
{{reflist}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Bitvis_UVVM_VHDL_Verification_Component_Framework&amp;diff=2925</id>
		<title>Bitvis UVVM VHDL Verification Component Framework</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Bitvis_UVVM_VHDL_Verification_Component_Framework&amp;diff=2925"/>
		<updated>2026-03-16T12:38:12Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: Updated some external references. Updated from Bitvis to UVVM framework&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is heavily based on the Powerpoint-presentation found [https://github.com/UVVM/UVVM/blob/master/uvvm_util/doc/Simple_TB_step_by_step.pps here].&amp;lt;ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copyright 2025 UVVM&lt;br /&gt;
Licensed under the [http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 (the “License”)]&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
UVVM (Universal VHDL Verification Methodology) is a free and Open Source Methodology and Library for making very structured VHDL-based testbenches, examples and simulations scripts from the [https://github.com/UVVM/UVVM UVVM on github]. &lt;br /&gt;
&lt;br /&gt;
=== What&#039;s in the folders? ===&lt;br /&gt;
[[File:20160302215840!1.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
The download includes severals folders:&lt;br /&gt;
* bitvis_irqc - example VHDL design + testbench&lt;br /&gt;
* bitvis_uart - example VHDL design + testbench&lt;br /&gt;
* bitvis_vip_sbi - Verification IP(VIP) for simple bus interface(SBI)&lt;br /&gt;
* bitvis_vip_uart - VIP for UART TX and RX&lt;br /&gt;
* uvvm_util - UVVM utility library - sufficient for simple testbenches&lt;br /&gt;
* uvvm_vvc_framework - Framework for more advanced tutorials&lt;br /&gt;
&lt;br /&gt;
=== IRQC ===&lt;br /&gt;
[[File:irqc.png|thumb]]&lt;br /&gt;
The provided example VHDL design is a simple interrupt controller with several internal registers, a bus interface and some input and output signals.&lt;br /&gt;
&lt;br /&gt;
[[File:irqc2.png|350px]]&lt;br /&gt;
&lt;br /&gt;
== UVVM Utility Library - Testbench creation ==&lt;br /&gt;
Copy the folders bitvis_irqc, bitvis_vip_sbi and uvvm_util to another location before editing the files.&lt;br /&gt;
=== Generate TB entity with DUT instantiated ===&lt;br /&gt;
Our TB entity can in many cases be generated from several tools. Notepad++ (among other) supports plugins that enables copying an entity and pasting it as an instantiation, and also as a complete testbench template. However, we will change some of our signals so that they fit the VIP SBI BFM. The signals to and from the CPU will be converted to t_sbi_if record, which is a type that includes all the SBI signals (cs, addr, rd, wr, wdata, ready and rdata).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--Standard libraries&lt;br /&gt;
library IEEE;&lt;br /&gt;
use IEEE.std_logic_1164.all;&lt;br /&gt;
use IEEE.numeric_std.all;&lt;br /&gt;
&lt;br /&gt;
-- Library enabling control of the simulation from VHDL. Eg. std.env.stop&lt;br /&gt;
library STD;&lt;br /&gt;
use std.env.all;&lt;br /&gt;
&lt;br /&gt;
-- Obviously the UVVM library&lt;br /&gt;
library uvvm_util;&lt;br /&gt;
context uvvm_util.uvvm_util_context;&lt;br /&gt;
&lt;br /&gt;
-- We will use this library later when implementing the Bus Functional Model&lt;br /&gt;
-- Includes among much else the record type t_sbi_if and many functions&lt;br /&gt;
-- If other buses are used, you will have to change this library&lt;br /&gt;
library bitvis_vip_sbi;&lt;br /&gt;
use bitvis_vip_sbi.sbi_bfm_pkg.all;&lt;br /&gt;
&lt;br /&gt;
-- This file includes definitions of everything from registers to record types&lt;br /&gt;
use work.irqc_pif_pkg.all;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Test case entity&lt;br /&gt;
entity irqc_tb is&lt;br /&gt;
end entity;&lt;br /&gt;
&lt;br /&gt;
-- Test case architecture&lt;br /&gt;
architecture func of irqc_tb is&lt;br /&gt;
&lt;br /&gt;
  -- DSP interface and general control signals&lt;br /&gt;
  signal clk           : std_logic  := &#039;0&#039;;&lt;br /&gt;
  signal arst          : std_logic  := &#039;0&#039;;&lt;br /&gt;
  -- CPU interface&lt;br /&gt;
  -- t_sbi_if is from the verification IP SBI&lt;br /&gt;
  -- init_sbi_if_signals initialize the inputs to 0 and the outputs to Z&lt;br /&gt;
  signal sbi_if : t_sbi_if(addr(2 downto 0), wdata(7 downto 0), rdata(7 downto 0)) := init_sbi_if_signals(3, 8);&lt;br /&gt;
  &lt;br /&gt;
  -- Interrupt related signals&lt;br /&gt;
  signal irq_source    : std_logic_vector(C_NUM_SOURCES-1 downto 0) := (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
  signal irq2cpu       : std_logic := &#039;0&#039;;&lt;br /&gt;
  signal irq2cpu_ack   : std_logic := &#039;0&#039;;&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
  -----------------------------------------------------------------------------&lt;br /&gt;
  -- Instantiate DUT&lt;br /&gt;
  -----------------------------------------------------------------------------&lt;br /&gt;
  i_irqc: entity work.irqc&lt;br /&gt;
    port map (&lt;br /&gt;
    -- DSP interface and general control signals&lt;br /&gt;
        clk             =&amp;gt; clk,&lt;br /&gt;
        arst            =&amp;gt; arst,&lt;br /&gt;
    -- CPU interface&lt;br /&gt;
        cs              =&amp;gt; sbi_if.cs,             -- NOTICE THE SIGNALS ARE NOW SBI_IF&lt;br /&gt;
        addr            =&amp;gt; sbi_if.addr,&lt;br /&gt;
        wr              =&amp;gt; sbi_if.wena,&lt;br /&gt;
        rd              =&amp;gt; sbi_if.rena,&lt;br /&gt;
        din             =&amp;gt; sbi_if.wdata,&lt;br /&gt;
        dout            =&amp;gt; sbi_if.rdata,&lt;br /&gt;
    -- Interrupt related signals&lt;br /&gt;
        irq_source      =&amp;gt; irq_source,&lt;br /&gt;
        irq2cpu         =&amp;gt; irq2cpu,&lt;br /&gt;
        irq2cpu_ack     =&amp;gt; irq2cpu_ack&lt;br /&gt;
        );&lt;br /&gt;
 &lt;br /&gt;
end func;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support process for clock generation ===&lt;br /&gt;
We now have to add a support process that controls the clock. This has to allow enabling/disabling from the test sequencer. We add the following before &amp;quot;begin&amp;quot; in our architecture:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-- Added for clock generation&lt;br /&gt;
  signal clock_ena  : boolean := false;&lt;br /&gt;
&lt;br /&gt;
  constant C_CLK_PERIOD : time := 10 ns;&lt;br /&gt;
  &lt;br /&gt;
  procedure clock_gen(&lt;br /&gt;
    signal   clock_signal  : inout std_logic;&lt;br /&gt;
    signal   clock_ena     : in    boolean;&lt;br /&gt;
    constant clock_period  : in    time&lt;br /&gt;
  ) is&lt;br /&gt;
    variable v_first_half_clk_period : time := C_CLK_PERIOD / 2;&lt;br /&gt;
  begin&lt;br /&gt;
    loop&lt;br /&gt;
      if not clock_ena then&lt;br /&gt;
        wait until clock_ena;&lt;br /&gt;
      end if;&lt;br /&gt;
      wait for v_first_half_clk_period;&lt;br /&gt;
      clock_signal &amp;lt;= not clock_signal;&lt;br /&gt;
      wait for (clock_period - v_first_half_clk_period);&lt;br /&gt;
      clock_signal &amp;lt;= not clock_signal;&lt;br /&gt;
    end loop;&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our clock can now be activated from the test sequencer (this will be added in the next step):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-- After begin in the architecture&lt;br /&gt;
clock_gen(clk, clock_ena, C_CLK_PERIOD);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Inside the test sequencer process&lt;br /&gt;
clock_ena &amp;lt;= true;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add test sequencer process ===&lt;br /&gt;
The next step is to add the test sequencer process. This process controls everything from initialization to termination of the simulation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 -- Set upt clock generator&lt;br /&gt;
  clock_gen(clk, clock_ena, C_CLK_PERIOD);      &lt;br /&gt;
 &lt;br /&gt;
  ------------------------------------------------&lt;br /&gt;
  -- PROCESS: p_main&lt;br /&gt;
  ------------------------------------------------&lt;br /&gt;
  p_main : process&lt;br /&gt;
  -- The scope tells you where log messages originates - C_SCOPE tells us they originate from the default test sequencer scope&lt;br /&gt;
  constant C_SCOPE     : string  := C_TB_SCOPE_DEFAULT;&lt;br /&gt;
  -- This is where we will add some procedures later to simplify the tests&lt;br /&gt;
  &lt;br /&gt;
  begin&lt;br /&gt;
  &lt;br /&gt;
  --Print the configuration to the log&lt;br /&gt;
  report_global_ctrl(VOID);&lt;br /&gt;
  report_msg_id_panel(VOID);&lt;br /&gt;
  &lt;br /&gt;
  enable_log_msg(ALL_MESSAGES);&lt;br /&gt;
  --disable_log_msg&lt;br /&gt;
  --enable_log_msg(ID_LOG_HDR);&lt;br /&gt;
  &lt;br /&gt;
  log(ID_LOG_HDR, &amp;quot;Start Simulation of TB for IRQC&amp;quot;, C_SCOPE);&lt;br /&gt;
  ------------------------------------------------------------&lt;br /&gt;
  clock_ena &amp;lt;= true;   -- to start clock generator&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  ------------------------------------------------------------&lt;br /&gt;
  -- End the simulation&lt;br /&gt;
  wait for 1000 ns;                       -- to allow some time for completion&lt;br /&gt;
  report_alert_counters(FINAL);            -- Report final counters and print conclusion for simulation (Success/Fail)&lt;br /&gt;
  log(ID_LOG_HDR, &amp;quot;SIMULATION COMPLETED&amp;quot;, C_SCOPE);&lt;br /&gt;
  &lt;br /&gt;
  --Finish the simulation&lt;br /&gt;
  std.env.stop;&lt;br /&gt;
  wait; -- to stop completely&lt;br /&gt;
  end process p_main;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Simulation==&lt;br /&gt;
We now have the skeleton of the testbench, which we will develop further. But now, let&#039;s see if everything works. UVVM includes simulation scripts for the IRQC example that compiles everything we need, from the source files of the VHDL design, to the testbench (if you called the file irqc_tb.vhd and placed it in the tb-folder) and the SBI BFM and the UVVM library. Open up QuestaSim/ModelSim.&lt;br /&gt;
Change directory to the script folder (where you have copied the UVVM files), for example in phys321/bitviswiki.....:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ~/phys321/bitviswiki/bitvis_irqc/script&lt;br /&gt;
do compile_and_sim_all.do&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will present our result in the transcript windows, but also write _Log.txt file which includes all the information we have asked for. We see that we get the results from the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
report_global_ctrl(VOID);&lt;br /&gt;
report_msg_id_panel(VOID);&lt;br /&gt;
enable_log_msg(ALL_MESSAGES);&lt;br /&gt;
log(ID_LOG_HDR, &amp;quot;Start Simulation of TB for IRQC&amp;quot;, C_SCOPE);&lt;br /&gt;
report_alert_counters(FINAL);&lt;br /&gt;
log(ID_LOG_HDR, &amp;quot;SIMULATION COMPLETED&amp;quot;, C_SCOPE);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Commenting these out will result in an empty log.&lt;br /&gt;
&lt;br /&gt;
== Verbosity control ==&lt;br /&gt;
We want to able to control the amount of information in our logs, and the framework enables us to prioritize messages based on ID. This makes it easy to turn on or off the information we want.&lt;br /&gt;
To turn on a specific ID&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
enable_log_msg(IDNAME);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Turn off:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disable_log_msg(IDNAME);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For writing a message to a certain log ID:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
log(IDNAME, &amp;quot;MESSAGE HERE&amp;quot;, C_SCOPE);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Remember that C_SCOPE just tells us that the message originated from the default scope and will look like &amp;quot;TB seq.&amp;quot; in the log file.&lt;br /&gt;
&lt;br /&gt;
Exampled IDs:&lt;br /&gt;
* ID_LOG_HDR,           -- ONLY allowed in test sequencer, Log section headers&lt;br /&gt;
* ID_SEQUENCER,         -- ONLY allowed in test sequencer, Normal log (not log headers)&lt;br /&gt;
* ID_BFM,               -- Used inside a BFM (to log BFM access)&lt;br /&gt;
* ID_CLOCK_GEN,         -- Used for logging when clock generators are enabled or disabled&lt;br /&gt;
* ALL_MESSAGES          -- Applies to ALL message ID apart from ID_NEVER&lt;br /&gt;
&lt;br /&gt;
You&#039;ll find all the different ID&#039;s in the UVVM Utility Library Quick Reference or defined in uvvm_util/adaptions_pkg.vhd. This also where C_TB_SCOPE_DEFAULT is defined.&lt;br /&gt;
&lt;br /&gt;
== Implement first tests ==&lt;br /&gt;
[[File:tb.png|thumb|upright=0.35]]&lt;br /&gt;
We want to check and verify that our testbench is up and running and to verify our first tests of the DUT. This means that we have to able to set all our signals passive, apply a reset signal and then check the default outputs of the DUT.&lt;br /&gt;
&lt;br /&gt;
Instead of setting all our signals passive one-by-one in our test sequencer we declare a procedure in our p_main process(this is done before begin):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
procedure set_inputs_passive(&lt;br /&gt;
      dummy   : t_void) is           --dummy variable is included only to allow calling the procedure with parenthesis for readability&lt;br /&gt;
    begin&lt;br /&gt;
      sbi_if.cs           &amp;lt;= &#039;0&#039;;&lt;br /&gt;
      sbi_if.addr         &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
      sbi_if.wena         &amp;lt;= &#039;0&#039;;&lt;br /&gt;
      sbi_if.rena         &amp;lt;= &#039;0&#039;;&lt;br /&gt;
      sbi_if.wdata          &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
      irq_source   &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
      irq2cpu_ack  &amp;lt;= &#039;0&#039;;&lt;br /&gt;
      log(ID_SEQUENCER_SUB, &amp;quot;All inputs set passive&amp;quot;, C_SCOPE);&lt;br /&gt;
    end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the procedure declaration also includes a dummy variable parameter. This means that we will be able to call the procedure with the more readable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set_inputs_passive(VOID);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rather than:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set_inputs_passive;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
which is more ambigious.&lt;br /&gt;
&lt;br /&gt;
We may also would like to send pulses on different signals, f.ex. sending a pulse on our reset to see if it behaves like intended. We therefore can include a pulse procedure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
procedure pulse(&lt;br /&gt;
      signal   target        : inout  std_logic_vector;&lt;br /&gt;
      constant pulse_value   : in     std_logic_vector;&lt;br /&gt;
      signal   clock_signal  : in     std_logic;&lt;br /&gt;
      constant num_periods   : in     natural;&lt;br /&gt;
      constant msg           : in     string) is&lt;br /&gt;
    begin&lt;br /&gt;
      if num_periods &amp;gt; 0 then&lt;br /&gt;
        wait until falling_edge(clock_signal);&lt;br /&gt;
        target &amp;lt;= pulse_value;&lt;br /&gt;
        for i in 1 to num_periods loop&lt;br /&gt;
          wait until falling_edge(clock_signal);&lt;br /&gt;
        end loop;&lt;br /&gt;
      else&lt;br /&gt;
        target &amp;lt;= pulse_value;&lt;br /&gt;
        wait for 0 ns;  -- Delta cycle only&lt;br /&gt;
      end if;&lt;br /&gt;
      target(target&#039;range) &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
      log(ID_SEQUENCER_SUB, &amp;quot;Pulsed to &amp;quot; &amp;amp; to_string(pulse_value, HEX, AS_IS, INCL_RADIX) &amp;amp; &amp;quot;. &amp;quot; &amp;amp; msg, C_SCOPE);&lt;br /&gt;
    end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example the test sequencer is required to inform the procedure of what value the pulse is to take. The call to the procedure would take the following form:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
pulse(arst, &#039;Z&#039;, clk, 10, &amp;quot;Log message - Im pulsing the value &#039;Z&#039;&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
But a more specific overload can be created where pulse always takes value &#039;1&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
procedure pulse(&lt;br /&gt;
      signal   target          : inout std_logic;&lt;br /&gt;
      signal   clock_signal    : in    std_logic;&lt;br /&gt;
      constant num_periods     : in    natural;&lt;br /&gt;
      constant msg             : in    string&lt;br /&gt;
    ) is&lt;br /&gt;
    begin&lt;br /&gt;
      if num_periods &amp;gt; 0 then&lt;br /&gt;
        wait until falling_edge(clock_signal);&lt;br /&gt;
        target  &amp;lt;= &#039;1&#039;;&lt;br /&gt;
        for i in 1 to num_periods loop&lt;br /&gt;
          wait until falling_edge(clock_signal);&lt;br /&gt;
        end loop;&lt;br /&gt;
      else&lt;br /&gt;
        target  &amp;lt;= &#039;1&#039;;&lt;br /&gt;
        wait for 0 ns;  -- Delta cycle only&lt;br /&gt;
      end if;&lt;br /&gt;
      target  &amp;lt;= &#039;0&#039;;&lt;br /&gt;
      log(ID_SEQUENCER_SUB, msg, C_SCOPE);&lt;br /&gt;
    end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These procedures can now be called directly from our test sequence:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set_inputs_passive(VOID);&lt;br /&gt;
pulse(arst, clk, 10, &amp;quot;pulsed reset-signal - active for 10T&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To check signal values we can use the built-in check function check_value():&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
check_value(irq2cpu, &#039;X&#039;, ERROR, &amp;quot;Interrupt to CPU must be default inactive&amp;quot;, C_SCOPE);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above call checks if the signal irq2cpu is &#039;X&#039;, and obviously fail if everything works correctly and gives the following message:&lt;br /&gt;
&lt;br /&gt;
[[File:error.png|700px]]&lt;br /&gt;
&lt;br /&gt;
If we want we can change the number of errors logged before the simulation stops:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set_alert_stop_limit(ERROR, 3);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We now have all the tools needed for the first tests in our sequencer:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set_inputs_passive(VOID);&lt;br /&gt;
pulse(arst, clk, 10, &amp;quot;Pulsed reset-signal - active for 10T&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
check_value(C_NUM_SOURCES &amp;gt; 0, FAILURE, &amp;quot;Must be at least 1 interrupt source&amp;quot;, C_SCOPE);&lt;br /&gt;
check_value(C_NUM_SOURCES &amp;lt;= 8, TB_WARNING, &amp;quot;This TB is only checking IRQC with up to 8 interrupt sources&amp;quot;, C_SCOPE);&lt;br /&gt;
  &lt;br /&gt;
log(ID_LOG_HDR, &amp;quot;Check defaults on output ports&amp;quot;, C_SCOPE);&lt;br /&gt;
------------------------------------------------------------&lt;br /&gt;
check_value(irq2cpu, &#039;0&#039;, ERROR, &amp;quot;Interrupt to CPU must be default inactive&amp;quot;, C_SCOPE);&lt;br /&gt;
check_value(sbi_if.rdata, x&amp;quot;00&amp;quot;, ERROR, &amp;quot;Register data bus output must be default passive&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will give us the following log:&lt;br /&gt;
&lt;br /&gt;
[[File:sim.png|800px]]&lt;br /&gt;
&lt;br /&gt;
This information may only interesting initially and for debug, and can be turned on or off by use of ID.&lt;br /&gt;
&lt;br /&gt;
== Subprograms ==&lt;br /&gt;
Some of our testbench code will be repeated several times and the testbench may therefore benefit from creating several subprograms. Obvious examples for our IRQC is:&lt;br /&gt;
- Register access&lt;br /&gt;
- Signal checkers&lt;br /&gt;
- Interrupt source pulsing?&lt;br /&gt;
- Interrupt acknowledge pulsing?&lt;br /&gt;
- (Report/log method)&lt;br /&gt;
- (Alert-handling)&lt;br /&gt;
- (reset, set_passive, ...)&lt;br /&gt;
&lt;br /&gt;
We&#039;ve already created and declared set_passive and pulse procedures, but we could f.ex create overloads for UVVM procedures:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    -- Log overloads for simplification&lt;br /&gt;
    procedure log(&lt;br /&gt;
      msg   : string) is&lt;br /&gt;
    begin&lt;br /&gt;
      log(ID_SEQUENCER, msg, C_SCOPE);&lt;br /&gt;
    end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This exact function is already overloaded in the UVVM packages, so including this in our testbench would produce compilation errors. So, let&#039;s not include it, but view it as an example of how it&#039;s done.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s say that it is probable that we&#039;ll want to change the number of interrupt sources that the controller can handle. We will then want to able to easily change vectors to the appropriate size. One way is to declare procedures that can trim and fit vectors. This way we can simply change a constant to change the number of sources.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  subtype t_irq_source is std_logic_vector(C_NUM_SOURCES-1 downto 0);&lt;br /&gt;
&lt;br /&gt;
  -- Trim (cut) a given vector to fit the number of irq sources (i.e. pot. reduce width)&lt;br /&gt;
  function trim(&lt;br /&gt;
    constant source   : std_logic_vector;&lt;br /&gt;
    constant num_bits : positive := C_NUM_SOURCES)&lt;br /&gt;
  return t_irq_source is&lt;br /&gt;
    variable v_result : std_logic_vector(source&#039;length-1 downto 0) := source;&lt;br /&gt;
  begin&lt;br /&gt;
    return v_result(num_bits-1 downto 0);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  -- Fit a given vector to the number of irq sources by masking with zeros above irq width&lt;br /&gt;
  function fit(&lt;br /&gt;
    constant source   : std_logic_vector;&lt;br /&gt;
    constant num_bits : positive := C_NUM_SOURCES)&lt;br /&gt;
  return std_logic_vector is&lt;br /&gt;
    variable v_result : std_logic_vector(source&#039;length-1 downto 0) := (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
    variable v_source : std_logic_vector(source&#039;length-1 downto 0) := source;&lt;br /&gt;
  begin&lt;br /&gt;
    v_result(num_bits-1 downto 0) := v_source(num_bits-1 downto 0);&lt;br /&gt;
    return v_result;&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All IRQC-dedicated subprograms should be declared locally, but more common (f.ex bus-specific) should be declared in common package that can be shared with other.&lt;br /&gt;
&lt;br /&gt;
== Register access ==&lt;br /&gt;
To access the IRQC&#039;s registers we need to go through the actual process of writing and reading data from them. Fortunately, Bitvis have already taken the responsibility of writing the BFM for the SBI. This doesn&#039;t mean that we doesn&#039;t have to understand what&#039;s going on, since we&#039;ll have to write our own BFM&#039;s for other buses that we use(Avalon, AXI, etc). &#039;&#039;&#039;January 2017 Bitvis announced that they released VVC for Avalon-MM and AXI4-lite.&#039;&#039;&#039; So we should investigate the BFM procedures. We want to check register values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
procedure sbi_check (&lt;br /&gt;
    constant addr_value   : in    unsigned;&lt;br /&gt;
    constant data_exp     : in    std_logic_vector;&lt;br /&gt;
    constant msg          : in    string;&lt;br /&gt;
    signal   clk          : in    std_logic;&lt;br /&gt;
    signal   cs           : inout std_logic;&lt;br /&gt;
    signal   addr         : inout unsigned;&lt;br /&gt;
    signal   rd           : inout std_logic;&lt;br /&gt;
    signal   wr           : inout std_logic;&lt;br /&gt;
    signal   ready        : in    std_logic;&lt;br /&gt;
    signal   rdata        : in    std_logic_vector;&lt;br /&gt;
    constant alert_level  : in    t_alert_level     := error;&lt;br /&gt;
    constant scope        : in    string            := C_SCOPE;&lt;br /&gt;
    constant msg_id_panel : in    t_msg_id_panel    := shared_msg_id_panel;&lt;br /&gt;
    constant config       : in    t_sbi_bfm_config  := C_SBI_BFM_CONFIG_DEFAULT&lt;br /&gt;
  ) is&lt;br /&gt;
    constant proc_name    : string :=  &amp;quot;sbi_check&amp;quot;;&lt;br /&gt;
    constant proc_call    : string :=  &amp;quot;sbi_check(A:&amp;quot; &amp;amp; to_string(addr_value, HEX, AS_IS, INCL_RADIX) &amp;amp;&lt;br /&gt;
                                       &amp;quot;, &amp;quot;  &amp;amp; to_string(data_exp, HEX, AS_IS, INCL_RADIX) &amp;amp; &amp;quot;)&amp;quot;;&lt;br /&gt;
    -- Normalize to the DUT addr/data widths&lt;br /&gt;
    variable v_normalised_addr    : unsigned(addr&#039;length-1 downto 0) :=&lt;br /&gt;
      normalize_and_check(addr_value, addr, ALLOW_WIDER_NARROWER, &amp;quot;addr_value&amp;quot;, &amp;quot;sbi_core_in.addr&amp;quot;, msg);&lt;br /&gt;
    -- Helper variables&lt;br /&gt;
    variable v_data_value         : std_logic_vector(rdata&#039;length - 1 downto 0);&lt;br /&gt;
    variable v_check_ok           : boolean;&lt;br /&gt;
    variable v_clk_cycles_waited  : natural := 0;&lt;br /&gt;
  begin&lt;br /&gt;
    sbi_read(addr_value, v_data_value, msg, clk, cs, addr, rd, wr, ready, rdata, scope, msg_id_panel, config, proc_name);&lt;br /&gt;
&lt;br /&gt;
    -- Compare values, but ignore any leading zero&#039;s if widths are different.&lt;br /&gt;
    -- Use ID_NEVER so that check_value method does not log when check is OK,&lt;br /&gt;
    -- log it here instead.&lt;br /&gt;
    v_check_ok := check_value(v_data_value, data_exp, alert_level, msg, scope, HEX_BIN_IF_INVALID, SKIP_LEADING_0, ID_NEVER, msg_id_panel, proc_call);&lt;br /&gt;
    if v_check_ok then&lt;br /&gt;
      log(config.id_for_bfm, proc_call &amp;amp; &amp;quot;=&amp;gt; OK, read data = &amp;quot; &amp;amp; to_string(v_data_value, HEX, SKIP_LEADING_0, INCL_RADIX) &amp;amp; &amp;quot;. &amp;quot; &amp;amp; msg, scope, msg_id_panel);&lt;br /&gt;
    end if;&lt;br /&gt;
  end procedure;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We see that sbi_check() calls sbi_read() before it checks if the read value is the expected value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
procedure sbi_read (&lt;br /&gt;
    constant addr_value    : in     unsigned;&lt;br /&gt;
    variable data_value    : out    std_logic_vector;&lt;br /&gt;
    constant msg           : in     string;&lt;br /&gt;
    signal   clk           : in     std_logic;&lt;br /&gt;
    signal   cs            : inout  std_logic;&lt;br /&gt;
    signal   addr          : inout  unsigned;&lt;br /&gt;
    signal   rd            : inout  std_logic;&lt;br /&gt;
    signal   wr            : inout  std_logic;&lt;br /&gt;
    signal   ready         : in     std_logic;&lt;br /&gt;
    signal   rdata         : in     std_logic_vector;&lt;br /&gt;
    constant scope         : in     string            := C_SCOPE;&lt;br /&gt;
    constant msg_id_panel  : in     t_msg_id_panel    := shared_msg_id_panel;&lt;br /&gt;
    constant config        : in     t_sbi_bfm_config  := C_SBI_BFM_CONFIG_DEFAULT;&lt;br /&gt;
    constant proc_name     : in     string            := &amp;quot;sbi_read&amp;quot;  -- overwrite if called from other procedure like sbi_check&lt;br /&gt;
  ) is&lt;br /&gt;
    constant proc_call            : string := &amp;quot;sbi_read(A:&amp;quot; &amp;amp; to_string(addr_value, HEX, AS_IS, INCL_RADIX) &amp;amp; &amp;quot;)&amp;quot;;&lt;br /&gt;
    -- Normalize to the DUT addr/data widths&lt;br /&gt;
    variable v_normalised_addr    : unsigned(addr&#039;length-1 downto 0) :=&lt;br /&gt;
        normalize_and_check(addr_value, addr, ALLOW_WIDER_NARROWER, &amp;quot;addr_value&amp;quot;, &amp;quot;sbi_core_in.addr&amp;quot;, msg);&lt;br /&gt;
    variable v_data_value         : std_logic_vector(data_value&#039;range);&lt;br /&gt;
    variable v_clk_cycles_waited  : natural := 0;&lt;br /&gt;
  begin&lt;br /&gt;
    wait_until_given_time_after_rising_edge(clk, config.clock_period/4);&lt;br /&gt;
    cs   &amp;lt;= &#039;1&#039;;&lt;br /&gt;
    wr   &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    rd   &amp;lt;= &#039;1&#039;;&lt;br /&gt;
    addr &amp;lt;= v_normalised_addr;&lt;br /&gt;
    wait for config.clock_period;&lt;br /&gt;
    while (config.use_ready_signal and ready = &#039;0&#039;) loop&lt;br /&gt;
      if v_clk_cycles_waited = 0 then&lt;br /&gt;
        log(config.id_for_bfm_wait, proc_call &amp;amp; &amp;quot; waiting for response (sbi ready=0)&amp;quot; &amp;amp; msg, scope, msg_id_panel);&lt;br /&gt;
      end if;&lt;br /&gt;
      wait for config.clock_period;&lt;br /&gt;
      v_clk_cycles_waited := v_clk_cycles_waited + 1;&lt;br /&gt;
      check_value(v_clk_cycles_waited &amp;lt;= config.max_wait_cycles, config.max_wait_cycles_severity,&lt;br /&gt;
                  &amp;quot;: Timeout while waiting for sbi ready&amp;quot;, scope, ID_NEVER, msg_id_panel, proc_call);&lt;br /&gt;
    end loop;&lt;br /&gt;
&lt;br /&gt;
    cs  &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    rd  &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    v_data_value  := rdata;&lt;br /&gt;
    data_value    := v_data_value;&lt;br /&gt;
    if proc_name = &amp;quot;sbi_read&amp;quot; then&lt;br /&gt;
      log(config.id_for_bfm, proc_call &amp;amp; &amp;quot;=&amp;gt; &amp;quot; &amp;amp; to_string(v_data_value, HEX, SKIP_LEADING_0, INCL_RADIX) &amp;amp; &amp;quot;. &amp;quot; &amp;amp; msg, scope, msg_id_panel);&lt;br /&gt;
    else&lt;br /&gt;
      -- Log will be handled by calling procedure (e.g. sbi_check)&lt;br /&gt;
    end if;&lt;br /&gt;
  end procedure;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We don&#039;t want to (and probably shouldnt) call the sbi_check and providing all the parameters each time. Some of this can be solved by the overloads with more standard parameters, and with our own check procedures declared locally in our testbench:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    procedure check(&lt;br /&gt;
      constant addr_value   : in natural;&lt;br /&gt;
      constant data_exp     : in std_logic_vector;&lt;br /&gt;
      constant alert_level  : in t_alert_level;&lt;br /&gt;
      constant msg          : in string) is&lt;br /&gt;
    begin&lt;br /&gt;
      sbi_check(to_unsigned(addr_value, sbi_if.addr&#039;length), data_exp, msg,&lt;br /&gt;
            clk, sbi_if, alert_level, C_SCOPE);&lt;br /&gt;
    end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The write procedure is also very handy and should be understood:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  procedure sbi_write (&lt;br /&gt;
    constant addr_value   : in    unsigned;&lt;br /&gt;
    constant data_value   : in    std_logic_vector;&lt;br /&gt;
    constant msg          : in    string;&lt;br /&gt;
    signal   clk          : in    std_logic;&lt;br /&gt;
    signal   cs           : inout std_logic;&lt;br /&gt;
    signal   addr         : inout unsigned;&lt;br /&gt;
    signal   rd           : inout std_logic;&lt;br /&gt;
    signal   wr           : inout std_logic;&lt;br /&gt;
    signal   ready        : in    std_logic;&lt;br /&gt;
    signal   wdata        : inout std_logic_vector;&lt;br /&gt;
    constant scope        : in    string            := C_SCOPE;&lt;br /&gt;
    constant msg_id_panel : in    t_msg_id_panel    := shared_msg_id_panel;&lt;br /&gt;
    constant config       : in    t_sbi_bfm_config  := C_SBI_BFM_CONFIG_DEFAULT&lt;br /&gt;
  ) is&lt;br /&gt;
    constant proc_name  : string :=  &amp;quot;sbi_write&amp;quot;;&lt;br /&gt;
    constant proc_call  : string :=  &amp;quot;sbi_write(A:&amp;quot; &amp;amp; to_string(addr_value, HEX, AS_IS, INCL_RADIX) &amp;amp;&lt;br /&gt;
                                     &amp;quot;, &amp;quot; &amp;amp; to_string(data_value, HEX, AS_IS, INCL_RADIX) &amp;amp; &amp;quot;)&amp;quot;;&lt;br /&gt;
    -- Normalise to the DUT addr/data widths&lt;br /&gt;
    variable v_normalised_addr    : unsigned(addr&#039;length-1 downto 0) :=&lt;br /&gt;
        normalize_and_check(addr_value, addr, ALLOW_WIDER_NARROWER, &amp;quot;addr_value&amp;quot;, &amp;quot;sbi_core_in.addr&amp;quot;, msg);&lt;br /&gt;
    variable v_normalised_data    : std_logic_vector(wdata&#039;length-1 downto 0) :=&lt;br /&gt;
        normalize_and_check(data_value, wdata, ALLOW_NARROWER, &amp;quot;data_value&amp;quot;, &amp;quot;sbi_core_in.wdata&amp;quot;, msg);&lt;br /&gt;
    variable v_clk_cycles_waited  : natural := 0;&lt;br /&gt;
  begin&lt;br /&gt;
    wait_until_given_time_after_rising_edge(clk, config.clock_period/4);&lt;br /&gt;
    cs    &amp;lt;= &#039;1&#039;;&lt;br /&gt;
    wr    &amp;lt;= &#039;1&#039;;&lt;br /&gt;
    rd    &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    addr  &amp;lt;= v_normalised_addr;&lt;br /&gt;
    wdata &amp;lt;= v_normalised_data;&lt;br /&gt;
&lt;br /&gt;
    wait for config.clock_period;&lt;br /&gt;
    while (config.use_ready_signal and ready = &#039;0&#039;) loop&lt;br /&gt;
      if v_clk_cycles_waited = 0 then&lt;br /&gt;
        log(config.id_for_bfm_wait, proc_call &amp;amp; &amp;quot; waiting for response (sbi ready=0)&amp;quot; &amp;amp; msg, scope, msg_id_panel);&lt;br /&gt;
      end if;&lt;br /&gt;
      wait for config.clock_period;&lt;br /&gt;
      v_clk_cycles_waited := v_clk_cycles_waited + 1;&lt;br /&gt;
      check_value(v_clk_cycles_waited &amp;lt;= config.max_wait_cycles, config.max_wait_cycles_severity,&lt;br /&gt;
                  &amp;quot;: Timeout while waiting for sbi ready&amp;quot;, scope, ID_NEVER, msg_id_panel, proc_call);&lt;br /&gt;
    end loop;&lt;br /&gt;
&lt;br /&gt;
    cs  &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    wr  &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    log(config.id_for_bfm, proc_call &amp;amp; &amp;quot; completed. &amp;quot; &amp;amp; msg, scope, msg_id_panel);&lt;br /&gt;
  end procedure;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We will create a local overload of this too:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
procedure write(&lt;br /&gt;
      constant addr_value   : in natural;&lt;br /&gt;
      constant data_value   : in std_logic_vector;&lt;br /&gt;
      constant msg          : in string) is&lt;br /&gt;
    begin&lt;br /&gt;
      sbi_write(to_unsigned(addr_value, sbi_if.addr&#039;length), data_value, msg,&lt;br /&gt;
            clk, sbi_if, C_SCOPE);&lt;br /&gt;
    end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We also need to set the sbi_if.ready signal high for this to work:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clock_generator(clk, clock_ena, C_CLK_PERIOD, &amp;quot;IRQC TB clock&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
-- Insert this here by the clock generator&lt;br /&gt;
sbi_if.ready &amp;lt;= &#039;1&#039;; -- always ready in the same clock cycle.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All this enables us to handle transactions at a high level. See UVVM documentation for how to write your own BFM and what it should include(sanity checks, etc).&lt;br /&gt;
&lt;br /&gt;
[[File:bfm.png|550px]]&lt;br /&gt;
&lt;br /&gt;
== Checking register write and read ==&lt;br /&gt;
Now we&#039;re enabled to write to and read from the registers. The register addresses are defined in the IRQC package file irqc_pif_bkg.vhd. Notice that we also use the previously declared overloaded version of log() and fit().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
log(ID_LOG_HDR, &amp;quot;Check register defaults and access (write + read)&amp;quot;, C_SCOPE);&lt;br /&gt;
    ------------------------------------------------------------&lt;br /&gt;
    log(&amp;quot;\nChecking Register defaults&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, x&amp;quot;00&amp;quot;, ERROR, &amp;quot;IRR default&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IER, x&amp;quot;00&amp;quot;, ERROR, &amp;quot;IER default&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IPR, x&amp;quot;00&amp;quot;, ERROR, &amp;quot;IPR default&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRQ2CPU_ALLOWED, x&amp;quot;00&amp;quot;, ERROR, &amp;quot;IRQ2CPU_ALLOWED default&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    log(&amp;quot;\nChecking Register Write/Read&amp;quot;);&lt;br /&gt;
    write(C_ADDR_IER, fit(x&amp;quot;55&amp;quot;), &amp;quot;IER&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IER, fit(x&amp;quot;55&amp;quot;), ERROR, &amp;quot;IER pure readback&amp;quot;);&lt;br /&gt;
    write(C_ADDR_IER, fit(x&amp;quot;AA&amp;quot;), &amp;quot;IER&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IER, fit(x&amp;quot;AA&amp;quot;), ERROR, &amp;quot;IER pure readback&amp;quot;);&lt;br /&gt;
    write(C_ADDR_IER, fit(x&amp;quot;00&amp;quot;), &amp;quot;IER&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IER, fit(x&amp;quot;00&amp;quot;), ERROR, &amp;quot;IER pure readback&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This check will give us a nice log if everything turns out ok:&lt;br /&gt;
&lt;br /&gt;
[[File:sim2.png|700px]]&lt;br /&gt;
&lt;br /&gt;
However, if there&#039;s an error:&lt;br /&gt;
&lt;br /&gt;
[[File:error2.png|700px]]&lt;br /&gt;
&lt;br /&gt;
== Further tests ==&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve tested register read/write, we should test the trigger/clear mechanism. No further adding of procedures are necessary.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    log(ID_LOG_HDR, &amp;quot;Check register trigger/clear mechanism&amp;quot;, C_SCOPE);&lt;br /&gt;
    ------------------------------------------------------------&lt;br /&gt;
    write(C_ADDR_ITR, fit(x&amp;quot;AA&amp;quot;), &amp;quot;ITR : Set interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;AA&amp;quot;), ERROR, &amp;quot;IRR&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ITR, fit(x&amp;quot;55&amp;quot;), &amp;quot;ITR : Set more interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;FF&amp;quot;), ERROR, &amp;quot;IRR&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ICR, fit(x&amp;quot;71&amp;quot;), &amp;quot;ICR : Clear interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;8E&amp;quot;), ERROR, &amp;quot;IRR&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ICR, fit(x&amp;quot;85&amp;quot;), &amp;quot;ICR : Clear interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;0A&amp;quot;), ERROR, &amp;quot;IRR&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ITR, fit(x&amp;quot;55&amp;quot;), &amp;quot;ITR : Set more interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;5F&amp;quot;), ERROR, &amp;quot;IRR&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ICR, fit(x&amp;quot;5F&amp;quot;), &amp;quot;ICR : Clear interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;00&amp;quot;), ERROR, &amp;quot;IRR&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The UVVM Utility Library provides all necessary functions and procedures to do further tests. F.ex. we should send pulses on the irq_source signal to check if the design behaves correctly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
log(ID_LOG_HDR, &amp;quot;Check interrupt sources, IER, IPR and irq2cpu&amp;quot;, C_SCOPE);&lt;br /&gt;
    ------------------------------------------------------------&lt;br /&gt;
    log(&amp;quot;\nChecking interrupts and IRR&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ICR, fit(x&amp;quot;FF&amp;quot;), &amp;quot;ICR : Clear all interrupts&amp;quot;);&lt;br /&gt;
    pulse(irq_source, trim(x&amp;quot;AA&amp;quot;), clk, 1, &amp;quot;Pulse irq_source 1T&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;AA&amp;quot;), ERROR, &amp;quot;IRR after irq pulses&amp;quot;);&lt;br /&gt;
    pulse(irq_source, trim(x&amp;quot;01&amp;quot;), clk, 1, &amp;quot;Add more interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;AB&amp;quot;), ERROR, &amp;quot;IRR after irq pulses&amp;quot;);&lt;br /&gt;
    pulse(irq_source, trim(x&amp;quot;A1&amp;quot;), clk, 1, &amp;quot;Repeat same interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;AB&amp;quot;), ERROR, &amp;quot;IRR after irq pulses&amp;quot;);&lt;br /&gt;
    pulse(irq_source, trim(x&amp;quot;54&amp;quot;), clk, 1, &amp;quot;Add remaining interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;FF&amp;quot;), ERROR, &amp;quot;IRR after irq pulses&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ICR, fit(x&amp;quot;AA&amp;quot;), &amp;quot;ICR : Clear half the interrupts&amp;quot;);&lt;br /&gt;
    pulse(irq_source, trim(x&amp;quot;A0&amp;quot;), clk, 1, &amp;quot;Add more interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;F5&amp;quot;), ERROR, &amp;quot;IRR after irq pulses&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ICR, fit(x&amp;quot;FF&amp;quot;), &amp;quot;ICR : Clear all interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;00&amp;quot;), ERROR, &amp;quot;IRR after clearing all&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Check stable ===&lt;br /&gt;
Another test provided by UVVM is check_stable(). This function enables us to test if a signal is holding the same value for a minimum provided time. We must declare a variable that holds the time from which we want to test if the signal is stable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v_time_stamp := now;  -- time from which irq2cpu should be stable off until triggered&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Later we&#039;re now able to test if the signal has been holding the same value the whole period:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
check_stable(irq2cpu, (now - v_time_stamp), ERROR, &amp;quot;No spikes allowed on irq2cpu&amp;quot;, C_SCOPE);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remember to declare the variable in the process:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
variable v_time_stamp   : time := 0 ns;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Await value ===&lt;br /&gt;
To check if a signal gets the expected value within a specified time value we use await_vale(). The test below throws an error if irq2cpu doesn&#039;t obtain the value &#039;1&#039; within 0 ns(!). Therefore expected immediately:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
await_value(irq2cpu, &#039;1&#039;, 0 ns, C_CLK_PERIOD, ERROR, &amp;quot;Interrupt expected immediately&amp;quot;, C_SCOPE);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other useful functions ===&lt;br /&gt;
&lt;br /&gt;
Check the UVVM Utility Library Quick Reference for syntax details.&lt;br /&gt;
&lt;br /&gt;
==== await_change() ====&lt;br /&gt;
Expects and waits for a change on the given signal, inside a given time window. &lt;br /&gt;
&lt;br /&gt;
==== check_value_in_range() ====&lt;br /&gt;
Throws an error of the signal value is outside the specified minimum and maximum values.&lt;br /&gt;
&lt;br /&gt;
== UVVM VVC ==&lt;br /&gt;
Guide coming....&lt;br /&gt;
&lt;br /&gt;
== UVVM LICENCE AGREEMENT ==&lt;br /&gt;
{{reflist}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Main_Page&amp;diff=2924</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Main_Page&amp;diff=2924"/>
		<updated>2026-02-18T13:54:55Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: Fjernet Teknisk avdeling lenke siden den ikke er i bruk&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Velkommen til [http://www.uib.no/ift Institutt for Fysikk og Teknologis]Wiki=&lt;br /&gt;
&lt;br /&gt;
* [[DAMARA]]&lt;br /&gt;
* [[Detector lab]]&lt;br /&gt;
* [[Cherenkov Telescope Array - Norway]]&lt;br /&gt;
* [[Eksperimentalfysikk med prosjektoppgave - PHYS117]]&lt;br /&gt;
* [[Experimental Nuclear Physics group]]&lt;br /&gt;
* [[Microelectronics group]]&lt;br /&gt;
* [http://wiki.uib.no/nanolab Nano Lab]&lt;br /&gt;
* [[Particle Physics group]]&lt;br /&gt;
* [[GRIEG project &amp;quot;EarlyUniverse&amp;quot;]]&lt;br /&gt;
* [[Strålevern]]&lt;br /&gt;
&lt;br /&gt;
== Komme i gang ==&lt;br /&gt;
&lt;br /&gt;
* [[Få tilgang til å opprette eller redigere sider i wikien]]&lt;br /&gt;
* [http://meta.wikimedia.org/wiki/Help:Contents User&#039;s Guide]&lt;br /&gt;
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]&lt;br /&gt;
* [http://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Simulering_av_VHDL&amp;diff=2923</id>
		<title>Simulering av VHDL</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Simulering_av_VHDL&amp;diff=2923"/>
		<updated>2026-01-19T10:48:26Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Konstruksjon og simulering av VHDL-kode med Modelsim/Questa===&lt;br /&gt;
&lt;br /&gt;
==Innledning==&lt;br /&gt;
&lt;br /&gt;
Hensikten med denne oppgaven er å få et lite innblikk i bruk av høynivåspråk for simulering og uttesting av kretsløsninger. I denne oppgaven skal vi bruker VHDL (Very high speed integrated circuit Hardware Description Language), som er spesielt utviklet for elektronikk. VHDL er definert slik at det passer i en mengde sammenhenger, og er det vil derfor være uoverkommelig å gå inn på detaljer i denne oppgaven. Vi skal ta for oss noen eksempler:&lt;br /&gt;
&lt;br /&gt;
* Eksempel 1: Signalflyt i en SR-lås&lt;br /&gt;
&lt;br /&gt;
* Eksempel 2: Signaler og variable&lt;br /&gt;
&lt;br /&gt;
Et VHDL program består i hovedsak av ENTITY, som definerer tilkobling mellom programmet og omverden, og ARCHITECTURE, som definerer programmets funksjon. Den komplette VHDL-koden for eksempel 1 vist nederst på denne siden.Mentor Graphics har utviklet programvare (Modelsim//Questa) som gjør det mulig å beskrivem, simulere og feilsøke VHDL-kode. Fremgangsmåten for skriving, kompilering og simulering av VHDL-kode finner du under.&lt;br /&gt;
&lt;br /&gt;
==Starte Questa Sim==&lt;br /&gt;
Når man skal arbeide med Questa Sim fra Mentor Graphics skriv følgende kommando i et terminalvindu.&lt;br /&gt;
Generelt ligger programvaren i /eda/Siemens, og versjonene ligger i mapper sortert på årstall.&lt;br /&gt;
&lt;br /&gt;
 ssh -X mikroserver4&lt;br /&gt;
 export SALT_LICENSE_SERVER=&amp;quot;Sett inn rett lisensserver og port her&amp;quot;&lt;br /&gt;
 source /eda/Siemens/2025-26/scripts/QUESTA-ONE-SIM_2025.3_RHELx86.sh&lt;br /&gt;
 vsim &amp;amp;&lt;br /&gt;
&lt;br /&gt;
==Lage et nytt prosjekt==&lt;br /&gt;
&lt;br /&gt;
I den følgende teksten er det vist hvordan man kan utføre kompilering, etc. på kommandolinjen. Dette kan enten gjøres i fra X terminalvinduet, eller fra kommandolinjen i Questa. Hvis man velger å bruke Questa-miljøet er de fleste prosedyrer/kommandoer tilgjengelige under menyen.&lt;br /&gt;
&lt;br /&gt;
Start et nytt prosjekt med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
File &amp;gt; New &amp;gt; Project&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:questa_new_project.png]]&lt;br /&gt;
&lt;br /&gt;
Velg et fornuftig navn og katalog. Man kan gjerne ha flere uavhengige vhdl-filer i et prosjekt.&lt;br /&gt;
Det er en fordel å ha en hovedkatalog til vhdl prosjektene og en underkatalog for prosjektet fex /home/bruker/vhdl_prosjekt/sr_latch&lt;br /&gt;
&lt;br /&gt;
==Skriving av VHDL kode==&lt;br /&gt;
&lt;br /&gt;
En ny VHDL kode (et design beskrevet med VHDL kode) påbegynnes med å starte emacs i terminal vinduet eller ved å bruke den innebygde teksteditoren i Questa ved å velge Create New File. &lt;br /&gt;
&lt;br /&gt;
Det fine med emacs er at man kan velge VHDL-modus. Dette gjøres med å skrive &#039;&#039;M-x vhdl-mode&#039;&#039; (M står for &#039;&#039;Meta&#039;&#039; og er vanligvis definert som esc-knappen). I emacs har en menyer med alle valg oppe langs kanten som i andre teksteditorer, men programmet skiller seg litt ut med kommandolinjen nederst i vinduet. Når en f. eks. skal lagre filen en har skrevet blir denne kommandolinjen aktiv og en skriver inn sti og filnavn der. Når man lagrer er ikke navnet på kodefilen viktig, men det er fornuftig å kalle den det samme som ENTITY-delen, med &#039;&#039;.vhdl&#039;&#039; som &amp;quot;etternavn&amp;quot; (f. eks. sr_latch.vhdl).&lt;br /&gt;
&lt;br /&gt;
==Kompilering av VHDL kode==&lt;br /&gt;
&lt;br /&gt;
Koden kompileres med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vcom sr_latch.vhdl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hvis det er feil i koden vil det komme en melding i kommando vinduet. Dobbeltklikker du på feilen vil du få opp en liste over kompileringsprosessen og alle feilene. Dobbeltklikker du så på linjen som angir en feil så vises den respektive linjen i editoren.&lt;br /&gt;
&lt;br /&gt;
Merk at navnet til det kompilerte designet blir skrevet med små bokstaver, selv om du har brukt store bokstaver i ENTITY- eller ARCHITECTURE-navnet. Det kompilerte designet blir liggende i work-katalogen.&lt;br /&gt;
&lt;br /&gt;
==Simulering og debugging i Questa==&lt;br /&gt;
&lt;br /&gt;
Når koden kompilerer feilfritt kan den simuleres i Questa. Dette startes med:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vsim&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nå dukker det opp en rute der du skal velge hva som skal simuleres, utvid work og velg vhdl filen. Eventuellt kan du skrive vsim work.sr_latch i kommandovinduet&lt;br /&gt;
&lt;br /&gt;
Questa bruker et standard X-basert vindusoppsett, og er derfor noen forskjellig fra de andre Mentor-programmene. Når du starter simulatoren åpnes det et vindu som vist i figur 1. Begynn med å åpne diverse vinduer:&lt;br /&gt;
&lt;br /&gt;
* View &amp;gt; Wave&lt;br /&gt;
&lt;br /&gt;
* View &amp;gt; Objects&lt;br /&gt;
&lt;br /&gt;
* View &amp;gt; Locals&lt;br /&gt;
&lt;br /&gt;
Man kan også gi kommandoer i Questa-vinduet. F.eks.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
wave *&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dra de signalene du vil se på i wave vinduet fra object vinduet.&lt;br /&gt;
&lt;br /&gt;
Signalverdier settes med kommandoen &#039;force&#039; eller med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
force &amp;gt; Force (i &amp;quot;Signals&amp;quot; vinduet)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dersom et av signalene skal være klokkesignal, kan dette gjøres enkelt med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
force &amp;gt; Clock (i &amp;quot;Signals&amp;quot; vinduet)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Eksempler==&lt;br /&gt;
===Signalflyt i en SR-lås===&lt;br /&gt;
&lt;br /&gt;
Simuler SR-låsen. Begynn med å påtrykke stimuli til alle signaler ved tid 0 (t0). Bruk STEP-knappen for å simulere på delta-tid-nivå. (Om en holder musepekeren over knappene i Questa, kommer det en forklarende tekst opp.) Når verdiene er stabile kjører du i f.eks. 100 ns før du endrer stimuli (skriv &#039;&#039;run 100&#039;&#039; i et av vinduene). Tilsvarende kan du endre stimuli ved å skrive f.eks. &#039;&#039;force S 0&#039;&#039; i hoved-vinduet. Legg merke til den røde pilen som peker på den linjen som blir utført.&lt;br /&gt;
&lt;br /&gt;
Hvis du vil begynne på ny kan du velge&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
File &amp;gt; restart -f&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.ALL;&lt;br /&gt;
&lt;br /&gt;
ENTITY SR_latch IS&lt;br /&gt;
PORT (&lt;br /&gt;
  S  : IN std_logic ;&lt;br /&gt;
  R  : IN std_logic ;&lt;br /&gt;
  Q  : INOUT std_logic ;&lt;br /&gt;
  QB : INOUT std_logic );&lt;br /&gt;
END SR_latch;&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE behave OF SR_latch IS&lt;br /&gt;
&lt;br /&gt;
BEGIN  --  behave&lt;br /&gt;
  Q &amp;lt;= S nand QB;&lt;br /&gt;
  QB &amp;lt;= R nand Q;&lt;br /&gt;
END behave;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Signaler og variable===&lt;br /&gt;
&lt;br /&gt;
Simuler VHDL-koden under. Bruk Step eller Step Over for å følge prosedyrens utvikling linje for linje. Simulere med optimaliseringsopsjon &amp;quot;-voptargs=+acc&amp;quot; for å kunne se variablene i wave-vinduet:&lt;br /&gt;
&lt;br /&gt;
 vsim -voptargs=+acc sign_var&lt;br /&gt;
&lt;br /&gt;
Bruk View &amp;gt; Objects for å kikke på signalene og View &amp;gt; Local for å se innholdet i variablene. Forklar endringene i signaler og variable. Hva er forskjellen som funksjon av tid/delta-tid?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.ALL;&lt;br /&gt;
&lt;br /&gt;
ENTITY sign_var IS&lt;br /&gt;
  PORT (clk  : IN std_logic);&lt;br /&gt;
END sign_var;&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE difference OF sign_var IS&lt;br /&gt;
&lt;br /&gt;
signal SA: bit := &#039;0&#039;;&lt;br /&gt;
signal SB: bit := &#039;1&#039;;&lt;br /&gt;
&lt;br /&gt;
begin  --  difference&lt;br /&gt;
p_test: process&lt;br /&gt;
  variable A: bit := &#039;0&#039;;&lt;br /&gt;
  variable B: bit := &#039;1&#039;;&lt;br /&gt;
  begin&lt;br /&gt;
    wait until rising_edge(clk);&lt;br /&gt;
    A := B;&lt;br /&gt;
    B := A;&lt;br /&gt;
    SA &amp;lt;= SB after 5 ns;&lt;br /&gt;
    SB &amp;lt;= SA after 5 ns;&lt;br /&gt;
  end process p_test;&lt;br /&gt;
end architecture difference;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Simulering_av_VHDL&amp;diff=2922</id>
		<title>Simulering av VHDL</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Simulering_av_VHDL&amp;diff=2922"/>
		<updated>2026-01-19T10:46:09Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: /* Signalflyt i en SR-lås */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Konstruksjon og simulering av VHDL-kode med Modelsim/Questa===&lt;br /&gt;
&lt;br /&gt;
==Innledning==&lt;br /&gt;
&lt;br /&gt;
Hensikten med denne oppgaven er å få et lite innblikk i bruk av høynivåspråk for simulering og uttesting av kretsløsninger. I denne oppgaven skal vi bruker VHDL (Very high speed integrated circuit Hardware Description Language), som er spesielt utviklet for elektronikk. VHDL er definert slik at det passer i en mengde sammenhenger, og er det vil derfor være uoverkommelig å gå inn på detaljer i denne oppgaven. Vi skal ta for oss noen eksempler:&lt;br /&gt;
&lt;br /&gt;
* Eksempel 1: Signalflyt i en SR-lås&lt;br /&gt;
&lt;br /&gt;
* Eksempel 2: Signaler og variable&lt;br /&gt;
&lt;br /&gt;
Et VHDL program består i hovedsak av ENTITY, som definerer tilkobling mellom programmet og omverden, og ARCHITECTURE, som definerer programmets funksjon. Den komplette VHDL-koden for eksempel 1 vist nederst på denne siden.Mentor Graphics har utviklet programvare (Modelsim//Questa) som gjør det mulig å beskrivem, simulere og feilsøke VHDL-kode. Fremgangsmåten for skriving, kompilering og simulering av VHDL-kode finner du under.&lt;br /&gt;
&lt;br /&gt;
==Starte Questa Sim==&lt;br /&gt;
Når man skal arbeide med Questa Sim fra Mentor Graphics skriv følgende kommando i et terminalvindu.&lt;br /&gt;
Generelt ligger programvaren i /eda/Siemens, og versjonene ligger i mapper sortert på årstall.&lt;br /&gt;
&lt;br /&gt;
 ssh -X mikroserver4&lt;br /&gt;
 export SALT_LICENSE_SERVER=&amp;quot;Sett inn rett lisensserver og port her&amp;quot;&lt;br /&gt;
 source /eda/Siemens/2025-26/scripts/QUESTA-ONE-SIM_2025.3_RHELx86.sh&lt;br /&gt;
 vsim &amp;amp;&lt;br /&gt;
&lt;br /&gt;
==Lage et nytt prosjekt==&lt;br /&gt;
&lt;br /&gt;
I den følgende teksten er det vist hvordan man kan utføre kompilering, etc. på kommandolinjen. Dette kan enten gjøres i fra X terminalvinduet, eller fra kommandolinjen i Questa. Hvis man velger å bruke Questa-miljøet er de fleste prosedyrer/kommandoer tilgjengelige under menyen.&lt;br /&gt;
&lt;br /&gt;
Start et nytt prosjekt med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
File &amp;gt; New &amp;gt; Project&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:questa_new_project.png]]&lt;br /&gt;
&lt;br /&gt;
Velg et fornuftig navn og katalog. Man kan gjerne ha flere uavhengige vhdl-filer i et prosjekt.&lt;br /&gt;
Det er en fordel å ha en hovedkatalog til vhdl prosjektene og en underkatalog for prosjektet fex /home/bruker/vhdl_prosjekt/sr_latch&lt;br /&gt;
&lt;br /&gt;
==Skriving av VHDL kode==&lt;br /&gt;
&lt;br /&gt;
En ny VHDL kode (et design beskrevet med VHDL kode) påbegynnes med å starte emacs i terminal vinduet eller ved å bruke den innebygde teksteditoren i Questa ved å velge Create New File. &lt;br /&gt;
&lt;br /&gt;
Det fine med emacs er at man kan velge VHDL-modus. Dette gjøres med å skrive &#039;&#039;M-x vhdl-mode&#039;&#039; (M står for &#039;&#039;Meta&#039;&#039; og er vanligvis definert som esc-knappen). I emacs har en menyer med alle valg oppe langs kanten som i andre teksteditorer, men programmet skiller seg litt ut med kommandolinjen nederst i vinduet. Når en f. eks. skal lagre filen en har skrevet blir denne kommandolinjen aktiv og en skriver inn sti og filnavn der. Når man lagrer er ikke navnet på kodefilen viktig, men det er fornuftig å kalle den det samme som ENTITY-delen, med &#039;&#039;.vhdl&#039;&#039; som &amp;quot;etternavn&amp;quot; (f. eks. sr_latch.vhdl).&lt;br /&gt;
&lt;br /&gt;
==Kompilering av VHDL kode==&lt;br /&gt;
&lt;br /&gt;
Koden kompileres med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vcom sr_latch.vhdl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hvis det er feil i koden vil det komme en melding i kommando vinduet. Dobbeltklikker du på feilen vil du få opp en liste over kompileringsprosessen og alle feilene. Dobbeltklikker du så på linjen som angir en feil så vises den respektive linjen i editoren.&lt;br /&gt;
&lt;br /&gt;
Merk at navnet til det kompilerte designet blir skrevet med små bokstaver, selv om du har brukt store bokstaver i ENTITY- eller ARCHITECTURE-navnet. Det kompilerte designet blir liggende i work-katalogen.&lt;br /&gt;
&lt;br /&gt;
==Simulering og debugging i Questa==&lt;br /&gt;
&lt;br /&gt;
Når koden kompilerer feilfritt kan den simuleres i Questa. Dette startes med:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vsim&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nå dukker det opp en rute der du skal velge hva som skal simuleres, utvid work og velg vhdl filen. Eventuellt kan du skrive vsim work.sr_latch i kommandovinduet&lt;br /&gt;
&lt;br /&gt;
Questa bruker et standard X-basert vindusoppsett, og er derfor noen forskjellig fra de andre Mentor-programmene. Når du starter simulatoren åpnes det et vindu som vist i figur 1. Begynn med å åpne diverse vinduer:&lt;br /&gt;
&lt;br /&gt;
* View &amp;gt; Wave&lt;br /&gt;
&lt;br /&gt;
* View &amp;gt; Objects&lt;br /&gt;
&lt;br /&gt;
* View &amp;gt; Locals&lt;br /&gt;
&lt;br /&gt;
Man kan også gi kommandoer i Questa-vinduet. F.eks.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Wave *&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dra de signalene du vil se på i wave vinduet fra object vinduet.&lt;br /&gt;
&lt;br /&gt;
Signalverdier settes med kommandoen &#039;force&#039; eller med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Force &amp;gt; Force (i &amp;quot;Signals&amp;quot; vinduet)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dersom et av signalene skal være klokkesignal, kan dette gjøres enkelt med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Force &amp;gt; Clock (i &amp;quot;Signals&amp;quot; vinduet)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Eksempler==&lt;br /&gt;
===Signalflyt i en SR-lås===&lt;br /&gt;
&lt;br /&gt;
Simuler SR-låsen. Begynn med å påtrykke stimuli til alle signaler ved tid 0 (t0). Bruk STEP-knappen for å simulere på delta-tid-nivå. (Om en holder musepekeren over knappene i Questa, kommer det en forklarende tekst opp.) Når verdiene er stabile kjører du i f.eks. 100 ns før du endrer stimuli (skriv &#039;&#039;run 100&#039;&#039; i et av vinduene). Tilsvarende kan du endre stimuli ved å skrive f.eks. &#039;&#039;force S 0&#039;&#039; i hoved-vinduet. Legg merke til den røde pilen som peker på den linjen som blir utført.&lt;br /&gt;
&lt;br /&gt;
Hvis du vil begynne på ny kan du velge&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
File &amp;gt; Restart -f&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.ALL;&lt;br /&gt;
&lt;br /&gt;
ENTITY SR_latch IS&lt;br /&gt;
PORT (&lt;br /&gt;
  S  : IN std_logic ;&lt;br /&gt;
  R  : IN std_logic ;&lt;br /&gt;
  Q  : INOUT std_logic ;&lt;br /&gt;
  QB : INOUT std_logic );&lt;br /&gt;
END SR_latch;&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE behave OF SR_latch IS&lt;br /&gt;
&lt;br /&gt;
BEGIN  --  behave&lt;br /&gt;
  Q &amp;lt;= S nand QB;&lt;br /&gt;
  QB &amp;lt;= R nand Q;&lt;br /&gt;
END behave;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Signaler og variable===&lt;br /&gt;
&lt;br /&gt;
Simuler VHDL-koden under. Bruk Step eller Step Over for å følge prosedyrens utvikling linje for linje. Simulere med optimaliseringsopsjon &amp;quot;-voptargs=+acc&amp;quot; for å kunne se variablene i wave-vinduet:&lt;br /&gt;
&lt;br /&gt;
 vsim -voptargs=+acc sign_var&lt;br /&gt;
&lt;br /&gt;
Bruk View &amp;gt; Objects for å kikke på signalene og View &amp;gt; Local for å se innholdet i variablene. Forklar endringene i signaler og variable. Hva er forskjellen som funksjon av tid/delta-tid?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.ALL;&lt;br /&gt;
&lt;br /&gt;
ENTITY sign_var IS&lt;br /&gt;
  PORT (clk  : IN std_logic);&lt;br /&gt;
END sign_var;&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE difference OF sign_var IS&lt;br /&gt;
&lt;br /&gt;
signal SA: bit := &#039;0&#039;;&lt;br /&gt;
signal SB: bit := &#039;1&#039;;&lt;br /&gt;
&lt;br /&gt;
begin  --  difference&lt;br /&gt;
p_test: process&lt;br /&gt;
  variable A: bit := &#039;0&#039;;&lt;br /&gt;
  variable B: bit := &#039;1&#039;;&lt;br /&gt;
  begin&lt;br /&gt;
    wait until rising_edge(clk);&lt;br /&gt;
    A := B;&lt;br /&gt;
    B := A;&lt;br /&gt;
    SA &amp;lt;= SB after 5 ns;&lt;br /&gt;
    SB &amp;lt;= SA after 5 ns;&lt;br /&gt;
  end process p_test;&lt;br /&gt;
end architecture difference;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Simulering_av_VHDL&amp;diff=2921</id>
		<title>Simulering av VHDL</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Simulering_av_VHDL&amp;diff=2921"/>
		<updated>2026-01-19T10:45:14Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: /* Starte Questa Sim */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Konstruksjon og simulering av VHDL-kode med Modelsim/Questa===&lt;br /&gt;
&lt;br /&gt;
==Innledning==&lt;br /&gt;
&lt;br /&gt;
Hensikten med denne oppgaven er å få et lite innblikk i bruk av høynivåspråk for simulering og uttesting av kretsløsninger. I denne oppgaven skal vi bruker VHDL (Very high speed integrated circuit Hardware Description Language), som er spesielt utviklet for elektronikk. VHDL er definert slik at det passer i en mengde sammenhenger, og er det vil derfor være uoverkommelig å gå inn på detaljer i denne oppgaven. Vi skal ta for oss noen eksempler:&lt;br /&gt;
&lt;br /&gt;
* Eksempel 1: Signalflyt i en SR-lås&lt;br /&gt;
&lt;br /&gt;
* Eksempel 2: Signaler og variable&lt;br /&gt;
&lt;br /&gt;
Et VHDL program består i hovedsak av ENTITY, som definerer tilkobling mellom programmet og omverden, og ARCHITECTURE, som definerer programmets funksjon. Den komplette VHDL-koden for eksempel 1 vist nederst på denne siden.Mentor Graphics har utviklet programvare (Modelsim//Questa) som gjør det mulig å beskrivem, simulere og feilsøke VHDL-kode. Fremgangsmåten for skriving, kompilering og simulering av VHDL-kode finner du under.&lt;br /&gt;
&lt;br /&gt;
==Starte Questa Sim==&lt;br /&gt;
Når man skal arbeide med Questa Sim fra Mentor Graphics skriv følgende kommando i et terminalvindu.&lt;br /&gt;
Generelt ligger programvaren i /eda/Siemens, og versjonene ligger i mapper sortert på årstall.&lt;br /&gt;
&lt;br /&gt;
 ssh -X mikroserver4&lt;br /&gt;
 export SALT_LICENSE_SERVER=&amp;quot;Sett inn rett lisensserver og port her&amp;quot;&lt;br /&gt;
 source /eda/Siemens/2025-26/scripts/QUESTA-ONE-SIM_2025.3_RHELx86.sh&lt;br /&gt;
 vsim &amp;amp;&lt;br /&gt;
&lt;br /&gt;
==Lage et nytt prosjekt==&lt;br /&gt;
&lt;br /&gt;
I den følgende teksten er det vist hvordan man kan utføre kompilering, etc. på kommandolinjen. Dette kan enten gjøres i fra X terminalvinduet, eller fra kommandolinjen i Questa. Hvis man velger å bruke Questa-miljøet er de fleste prosedyrer/kommandoer tilgjengelige under menyen.&lt;br /&gt;
&lt;br /&gt;
Start et nytt prosjekt med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
File &amp;gt; New &amp;gt; Project&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:questa_new_project.png]]&lt;br /&gt;
&lt;br /&gt;
Velg et fornuftig navn og katalog. Man kan gjerne ha flere uavhengige vhdl-filer i et prosjekt.&lt;br /&gt;
Det er en fordel å ha en hovedkatalog til vhdl prosjektene og en underkatalog for prosjektet fex /home/bruker/vhdl_prosjekt/sr_latch&lt;br /&gt;
&lt;br /&gt;
==Skriving av VHDL kode==&lt;br /&gt;
&lt;br /&gt;
En ny VHDL kode (et design beskrevet med VHDL kode) påbegynnes med å starte emacs i terminal vinduet eller ved å bruke den innebygde teksteditoren i Questa ved å velge Create New File. &lt;br /&gt;
&lt;br /&gt;
Det fine med emacs er at man kan velge VHDL-modus. Dette gjøres med å skrive &#039;&#039;M-x vhdl-mode&#039;&#039; (M står for &#039;&#039;Meta&#039;&#039; og er vanligvis definert som esc-knappen). I emacs har en menyer med alle valg oppe langs kanten som i andre teksteditorer, men programmet skiller seg litt ut med kommandolinjen nederst i vinduet. Når en f. eks. skal lagre filen en har skrevet blir denne kommandolinjen aktiv og en skriver inn sti og filnavn der. Når man lagrer er ikke navnet på kodefilen viktig, men det er fornuftig å kalle den det samme som ENTITY-delen, med &#039;&#039;.vhdl&#039;&#039; som &amp;quot;etternavn&amp;quot; (f. eks. sr_latch.vhdl).&lt;br /&gt;
&lt;br /&gt;
==Kompilering av VHDL kode==&lt;br /&gt;
&lt;br /&gt;
Koden kompileres med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vcom sr_latch.vhdl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hvis det er feil i koden vil det komme en melding i kommando vinduet. Dobbeltklikker du på feilen vil du få opp en liste over kompileringsprosessen og alle feilene. Dobbeltklikker du så på linjen som angir en feil så vises den respektive linjen i editoren.&lt;br /&gt;
&lt;br /&gt;
Merk at navnet til det kompilerte designet blir skrevet med små bokstaver, selv om du har brukt store bokstaver i ENTITY- eller ARCHITECTURE-navnet. Det kompilerte designet blir liggende i work-katalogen.&lt;br /&gt;
&lt;br /&gt;
==Simulering og debugging i Questa==&lt;br /&gt;
&lt;br /&gt;
Når koden kompilerer feilfritt kan den simuleres i Questa. Dette startes med:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vsim&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nå dukker det opp en rute der du skal velge hva som skal simuleres, utvid work og velg vhdl filen. Eventuellt kan du skrive vsim work.sr_latch i kommandovinduet&lt;br /&gt;
&lt;br /&gt;
Questa bruker et standard X-basert vindusoppsett, og er derfor noen forskjellig fra de andre Mentor-programmene. Når du starter simulatoren åpnes det et vindu som vist i figur 1. Begynn med å åpne diverse vinduer:&lt;br /&gt;
&lt;br /&gt;
* View &amp;gt; Wave&lt;br /&gt;
&lt;br /&gt;
* View &amp;gt; Objects&lt;br /&gt;
&lt;br /&gt;
* View &amp;gt; Locals&lt;br /&gt;
&lt;br /&gt;
Man kan også gi kommandoer i Questa-vinduet. F.eks.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Wave *&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dra de signalene du vil se på i wave vinduet fra object vinduet.&lt;br /&gt;
&lt;br /&gt;
Signalverdier settes med kommandoen &#039;force&#039; eller med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Force &amp;gt; Force (i &amp;quot;Signals&amp;quot; vinduet)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dersom et av signalene skal være klokkesignal, kan dette gjøres enkelt med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Force &amp;gt; Clock (i &amp;quot;Signals&amp;quot; vinduet)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Eksempler==&lt;br /&gt;
===Signalflyt i en SR-lås===&lt;br /&gt;
&lt;br /&gt;
Simuler SR-låsen. Begynn med å påtrykke stimuli til alle signaler ved tid 0 (t0). Bruk STEP-knappen for å simulere på delta-tid-nivå. (Om en holder musepekeren over knappene i Questa, kommer det en forklarende tekst opp.) Når verdiene er stabile kjører du i f.eks. 100 ns før du endrer stimuli (skriv &#039;&#039;run 100&#039;&#039; i et av vinduene). Tilsvarende kan du endre stimuli ved å skrive f.eks. &#039;&#039;force S 0&#039;&#039; i hoved-vinduet. Legg merke til den røde pilen som peker på den linjen som blir utført.&lt;br /&gt;
&lt;br /&gt;
Hvis du vil begynne på ny kan du velge&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
File &amp;gt; Restart -f&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.ALL;&lt;br /&gt;
&lt;br /&gt;
ENTITY SR_latch IS&lt;br /&gt;
PORT (&lt;br /&gt;
S,R  : IN std_logic ;&lt;br /&gt;
Q,QB : INOUT std_logic );&lt;br /&gt;
END SR_latch;&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE behave OF SR_latch IS&lt;br /&gt;
&lt;br /&gt;
BEGIN  --  behave&lt;br /&gt;
Q &amp;lt;= S nand QB;&lt;br /&gt;
QB &amp;lt;= R nand Q;&lt;br /&gt;
END behave;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Signaler og variable===&lt;br /&gt;
&lt;br /&gt;
Simuler VHDL-koden under. Bruk Step eller Step Over for å følge prosedyrens utvikling linje for linje. Simulere med optimaliseringsopsjon &amp;quot;-voptargs=+acc&amp;quot; for å kunne se variablene i wave-vinduet:&lt;br /&gt;
&lt;br /&gt;
 vsim -voptargs=+acc sign_var&lt;br /&gt;
&lt;br /&gt;
Bruk View &amp;gt; Objects for å kikke på signalene og View &amp;gt; Local for å se innholdet i variablene. Forklar endringene i signaler og variable. Hva er forskjellen som funksjon av tid/delta-tid?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.ALL;&lt;br /&gt;
&lt;br /&gt;
ENTITY sign_var IS&lt;br /&gt;
  PORT (clk  : IN std_logic);&lt;br /&gt;
END sign_var;&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE difference OF sign_var IS&lt;br /&gt;
&lt;br /&gt;
signal SA: bit := &#039;0&#039;;&lt;br /&gt;
signal SB: bit := &#039;1&#039;;&lt;br /&gt;
&lt;br /&gt;
begin  --  difference&lt;br /&gt;
p_test: process&lt;br /&gt;
  variable A: bit := &#039;0&#039;;&lt;br /&gt;
  variable B: bit := &#039;1&#039;;&lt;br /&gt;
  begin&lt;br /&gt;
    wait until rising_edge(clk);&lt;br /&gt;
    A := B;&lt;br /&gt;
    B := A;&lt;br /&gt;
    SA &amp;lt;= SB after 5 ns;&lt;br /&gt;
    SB &amp;lt;= SA after 5 ns;&lt;br /&gt;
  end process p_test;&lt;br /&gt;
end architecture difference;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Detector_lab&amp;diff=2916</id>
		<title>Detector lab</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Detector_lab&amp;diff=2916"/>
		<updated>2025-04-22T09:54:16Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: /* Who are we? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Goal ==&lt;br /&gt;
The aim of our research is to study high energy particle detectors, and to develop new detectors for the future. In particular, we are interested in studying medical applications of these detectors and to help bridge fundamental with technological research.&lt;br /&gt;
&lt;br /&gt;
== Our projects ==&lt;br /&gt;
* [[PET Project]]&lt;br /&gt;
** [[Labview readout setup]]&lt;br /&gt;
** [[XYZ table setup]]&lt;br /&gt;
** [[Root analysis programs]]&lt;br /&gt;
* [[Calorimeter Activities]]&lt;br /&gt;
* [[CALICE]]&lt;br /&gt;
* [[3D Detector Activities]]&lt;br /&gt;
* [[phys117 - PET project]]&lt;br /&gt;
&lt;br /&gt;
== Who are we? ==&lt;br /&gt;
* Researcher: Heidi&lt;br /&gt;
* Professors: Bjarne, Dieter, Renate, [http://www.uib.no/personer/Kjetil.Ullaland Kjetil]&lt;br /&gt;
* Engineers: Attiq, Thomas&lt;br /&gt;
&lt;br /&gt;
== Our facilities ==&lt;br /&gt;
* The main laboratory is situated in the 3rd floor at the IFT, room 332 (55588306)&lt;br /&gt;
* The soldering lab, room 334&lt;br /&gt;
* The clean room, room 324&lt;br /&gt;
* [[The muon spectrometer]]&lt;br /&gt;
&lt;br /&gt;
== Lab Equipment ==&lt;br /&gt;
* [[Lab Equipment]] list, how to&#039;s, equipment service log&#039;s etc...&lt;br /&gt;
* [[Wishlist]] Put the things you will need for your projects here.&lt;br /&gt;
&lt;br /&gt;
== Health and Safety ==&lt;br /&gt;
* [[Retningslinjer for bruk av kapslede kilder ved IFT]]&lt;br /&gt;
* [http://www.uib.no/poa/hms-portalen UIB HMS Portalen]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* Our [https://subversion.uib.no/repos/detectorlab/ SVN]&lt;br /&gt;
* We can use this fileserver to store our collected data:&lt;br /&gt;
** Windows: \\ukl-felles\ift-kjernefys1\detectorlab&lt;br /&gt;
** Linux:   /Data/ift/ift_kjernefys1/detectorlab&lt;br /&gt;
&lt;br /&gt;
== Recent talks ==&lt;br /&gt;
04.11.09&lt;br /&gt;
* Dominik Fehlker - Presentation of the Lab [http://web.ift.uib.no/~dominik/files/detectorlabwiki/talks/part_phys_seminar_041109.ppt ppt] [http://web.ift.uib.no/~dominik/files/detectorlabwiki/talks/part_phys_seminar_041109.pdf pdf]&lt;br /&gt;
* Lars-Halvard Thunold Helleve - SiPM introduction [https://wikihost.uib.no/ift/images/d/dc/SiPM_small_talk_041109_Lars-Halvard.pdf pdf]&lt;br /&gt;
* Kristine Indahl Helle - 3D pixel detectors [[File:3D_Si_pixels.pdf]]&lt;br /&gt;
[[older presentations]]&lt;br /&gt;
&lt;br /&gt;
==Documentation==&lt;br /&gt;
In the [[documentation-list]] you can find relevant articles and masterthesis concerning the work in the lab.&lt;br /&gt;
&lt;br /&gt;
== Meetings and conferences ==&lt;br /&gt;
* 23.09. - 29.09.11: IEEE Nuclear Science Symposium and Medical Imaging Conference, Valencia (http://www.nss-mic.org/2011/)&lt;br /&gt;
* 26.09. - 30.09.11: TWEPP-11 Topical Workshop On Electronics For Particle Physics, Vienna (http://twepp11.hephy.at/)&lt;br /&gt;
&lt;br /&gt;
== For internal use ==&lt;br /&gt;
[[material]] that can be used in official presentations.&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=PHYS222&amp;diff=2913</id>
		<title>PHYS222</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=PHYS222&amp;diff=2913"/>
		<updated>2024-10-02T11:48:20Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Fagressurser for bruk i PHYS222 og PHYS223 ==&lt;br /&gt;
&lt;br /&gt;
=== Fagbøker ===&lt;br /&gt;
* [http://www.cmosvlsi.com/ CMOS VLSI Design: A Circuits and Systems Perspective]&lt;br /&gt;
* [http://www.ece.ucdavis.edu/sscrl/book_corrections/ghlm/corr/ List of known errors and corrections for Analysis and Design of Analog Integrated Circuits, Fourth Edition]&lt;br /&gt;
&lt;br /&gt;
=== Tutorials and lectures ===&lt;br /&gt;
* [http://www.electronics-tutorials.ws Basic Electronics Tutorials]&lt;br /&gt;
* [https://www.youtube.com/playlist?list=PLc7Gz02Znph-c2-ssFpRrzYwbzplXfXUT New Analog Circuit Design (By Prof. Ali Hajimiri, Caltech)]&lt;br /&gt;
* [https://www.khanacademy.org/science/electrical-engineering Electrical engineering (Khan Academy)]&lt;br /&gt;
&lt;br /&gt;
=== Noise ===&lt;br /&gt;
* [http://ieeexplore.ieee.org/search/srchabstract.jsp?arnumber=261888&amp;amp;isnumber=6598&amp;amp;punumber=101&amp;amp;k2dockey=261888@ieeejrns&amp;amp;query=261888%3Cin%3Earnumber&amp;amp;pos=0 White noise in MOS transistors and resistors]&lt;br /&gt;
* [http://www.stat.ualberta.ca/people/schmu/preprints/poisson.pdf Shark attacks and the Poisson approximation]&lt;br /&gt;
* [https://www.k-state.edu/edl/docs/pubs/technical-resources/Technote1.pdf Equivalent Noise Bandwidth]&lt;br /&gt;
&lt;br /&gt;
=== Halvlederfysikk ===&lt;br /&gt;
* [https://www.youtube.com/watch?v=Coy-WRCfems How does a diode work?]&lt;br /&gt;
* [http://hyperphysics.phy-astr.gsu.edu/HBASE/solids/semcn.html Hyperphysics om halvledere]&lt;br /&gt;
* [http://jas.eng.buffalo.edu/index.html Semiconductor Simulation Applets]&lt;br /&gt;
* [http://pveducation.org/ Photovoltaic Education Network]&lt;br /&gt;
* [http://www.semi1source.com/glossary/ Semiconductor Glossary]&lt;br /&gt;
&lt;br /&gt;
=== Prosessteknologi ===&lt;br /&gt;
* [http://micro.magnet.fsu.edu/electromag/java/transistor/index.html Explore how an individual Field Effect (FET) transistor is fabricated on a silicon wafer simultaneously with millions of its neighbours]&lt;br /&gt;
* [https://www.youtube.com/watch?v=Jctk0DI7YP8 Understanding The FinFet Semiconductor Process]&lt;br /&gt;
* [https://youtu.be/MvbP_TizoNs Problems and Solutions at 7nm]&lt;br /&gt;
* [https://youtu.be/Qo2ywUURSKg A tour inside Intel Corporation&#039;s D1D factory]&lt;br /&gt;
* [https://www.youtube.com/watch?v=W3rfVpkNquA Intel Ivy Bridge 22nm FinFET Process Fabrication]&lt;br /&gt;
* [https://youtu.be/ApWOf6J858Y Integrated circuit scaling to 10 nm and beyond - Mark Bohr, Intel Senior Fellow]&lt;br /&gt;
* [http://spectrum.ieee.org/semiconductors/devices/transistor-wars Transistor Wars - Rival architectures face off in a bid to keep Moore&#039;s Law alive]&lt;br /&gt;
&lt;br /&gt;
=== Logical effort ===&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Logical_effort Logical Effort Wikipedia]&lt;br /&gt;
&lt;br /&gt;
=== Matlab/Maple ===&lt;br /&gt;
Vi kan bruke Matlab/Maple for å løse ligninger og plotte resultater. Her er noen eksempler:&lt;br /&gt;
&lt;br /&gt;
* [[Symbolsk løsning av nodeligninger med Matlab]]&lt;br /&gt;
* [http://lpsa.swarthmore.edu/Bode/BodeHow.html The Asymptotic Bode Diagram: Derivation of Approximations]&lt;br /&gt;
=== Kretssimulering ===&lt;br /&gt;
&lt;br /&gt;
[[ Eksempler/Oppgaver ]]&lt;br /&gt;
&lt;br /&gt;
==== AIM-Spice ====&lt;br /&gt;
AIM-Spice is a new version of SPICE running under the Microsoft Windows and Linux operating systems. AIM-Spice for Windows is capable of displaying graphically the results of a simulation in progress, a feature that allows the operator to terminate a run based on an instant information on intermediate simulation results.&lt;br /&gt;
&lt;br /&gt;
SPICE is the most commonly used analogue circuit simulator today and is enormously important for the electronics industry. SPICE is a general purpose analogue simulator which contains models for most circuit elements and can handle complex non-linear circuits. The simulator can calculate dc operating points, perform transient analyses, locate poles and zeros for different kinds of transfer functions, find the small signal frequency response, small signal transfer functions, small signal sensitivities, and perform Fourier, noise, and distortion analyses.&lt;br /&gt;
&lt;br /&gt;
[http://www.aimspice.com/download.html Download a free student version]&lt;br /&gt;
&lt;br /&gt;
==== LTspice ====&lt;br /&gt;
&lt;br /&gt;
LTspice is a high performance Spice III simulator, schematic capture and waveform viewer with enhancements and models for easing the simulation of switching regulators. Included in this download are Spice, Macro Models for 80% of Linear Technology&#039;s switching regulators, over 200 op amp models, as well as resistors, transistors and MOSFET models. &lt;br /&gt;
&lt;br /&gt;
[http://www.linear.com/designtools/software/switchercad.jsp Download LTspice]&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=PHYS222&amp;diff=2912</id>
		<title>PHYS222</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=PHYS222&amp;diff=2912"/>
		<updated>2024-10-02T11:47:54Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: Added some lectures in Tutorials and lectures&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Fagressurser for bruk i PHYS222 og PHYS223 ==&lt;br /&gt;
&lt;br /&gt;
=== Fagbøker ===&lt;br /&gt;
* [http://www.cmosvlsi.com/ CMOS VLSI Design: A Circuits and Systems Perspective]&lt;br /&gt;
* [http://www.ece.ucdavis.edu/sscrl/book_corrections/ghlm/corr/ List of known errors and corrections for Analysis and Design of Analog Integrated Circuits, Fourth Edition]&lt;br /&gt;
&lt;br /&gt;
==== Tutorials and lectures ====&lt;br /&gt;
* [http://www.electronics-tutorials.ws Basic Electronics Tutorials]&lt;br /&gt;
* [https://www.youtube.com/playlist?list=PLc7Gz02Znph-c2-ssFpRrzYwbzplXfXUT New Analog Circuit Design (By Prof. Ali Hajimiri, Caltech)]&lt;br /&gt;
* [https://www.khanacademy.org/science/electrical-engineering Electrical engineering (Khan Academy)]&lt;br /&gt;
&lt;br /&gt;
=== Noise ===&lt;br /&gt;
* [http://ieeexplore.ieee.org/search/srchabstract.jsp?arnumber=261888&amp;amp;isnumber=6598&amp;amp;punumber=101&amp;amp;k2dockey=261888@ieeejrns&amp;amp;query=261888%3Cin%3Earnumber&amp;amp;pos=0 White noise in MOS transistors and resistors]&lt;br /&gt;
* [http://www.stat.ualberta.ca/people/schmu/preprints/poisson.pdf Shark attacks and the Poisson approximation]&lt;br /&gt;
* [https://www.k-state.edu/edl/docs/pubs/technical-resources/Technote1.pdf Equivalent Noise Bandwidth]&lt;br /&gt;
&lt;br /&gt;
=== Halvlederfysikk ===&lt;br /&gt;
* [https://www.youtube.com/watch?v=Coy-WRCfems How does a diode work?]&lt;br /&gt;
* [http://hyperphysics.phy-astr.gsu.edu/HBASE/solids/semcn.html Hyperphysics om halvledere]&lt;br /&gt;
* [http://jas.eng.buffalo.edu/index.html Semiconductor Simulation Applets]&lt;br /&gt;
* [http://pveducation.org/ Photovoltaic Education Network]&lt;br /&gt;
* [http://www.semi1source.com/glossary/ Semiconductor Glossary]&lt;br /&gt;
&lt;br /&gt;
=== Prosessteknologi ===&lt;br /&gt;
* [http://micro.magnet.fsu.edu/electromag/java/transistor/index.html Explore how an individual Field Effect (FET) transistor is fabricated on a silicon wafer simultaneously with millions of its neighbours]&lt;br /&gt;
* [https://www.youtube.com/watch?v=Jctk0DI7YP8 Understanding The FinFet Semiconductor Process]&lt;br /&gt;
* [https://youtu.be/MvbP_TizoNs Problems and Solutions at 7nm]&lt;br /&gt;
* [https://youtu.be/Qo2ywUURSKg A tour inside Intel Corporation&#039;s D1D factory]&lt;br /&gt;
* [https://www.youtube.com/watch?v=W3rfVpkNquA Intel Ivy Bridge 22nm FinFET Process Fabrication]&lt;br /&gt;
* [https://youtu.be/ApWOf6J858Y Integrated circuit scaling to 10 nm and beyond - Mark Bohr, Intel Senior Fellow]&lt;br /&gt;
* [http://spectrum.ieee.org/semiconductors/devices/transistor-wars Transistor Wars - Rival architectures face off in a bid to keep Moore&#039;s Law alive]&lt;br /&gt;
&lt;br /&gt;
=== Logical effort ===&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Logical_effort Logical Effort Wikipedia]&lt;br /&gt;
&lt;br /&gt;
=== Matlab/Maple ===&lt;br /&gt;
Vi kan bruke Matlab/Maple for å løse ligninger og plotte resultater. Her er noen eksempler:&lt;br /&gt;
&lt;br /&gt;
* [[Symbolsk løsning av nodeligninger med Matlab]]&lt;br /&gt;
* [http://lpsa.swarthmore.edu/Bode/BodeHow.html The Asymptotic Bode Diagram: Derivation of Approximations]&lt;br /&gt;
=== Kretssimulering ===&lt;br /&gt;
&lt;br /&gt;
[[ Eksempler/Oppgaver ]]&lt;br /&gt;
&lt;br /&gt;
==== AIM-Spice ====&lt;br /&gt;
AIM-Spice is a new version of SPICE running under the Microsoft Windows and Linux operating systems. AIM-Spice for Windows is capable of displaying graphically the results of a simulation in progress, a feature that allows the operator to terminate a run based on an instant information on intermediate simulation results.&lt;br /&gt;
&lt;br /&gt;
SPICE is the most commonly used analogue circuit simulator today and is enormously important for the electronics industry. SPICE is a general purpose analogue simulator which contains models for most circuit elements and can handle complex non-linear circuits. The simulator can calculate dc operating points, perform transient analyses, locate poles and zeros for different kinds of transfer functions, find the small signal frequency response, small signal transfer functions, small signal sensitivities, and perform Fourier, noise, and distortion analyses.&lt;br /&gt;
&lt;br /&gt;
[http://www.aimspice.com/download.html Download a free student version]&lt;br /&gt;
&lt;br /&gt;
==== LTspice ====&lt;br /&gt;
&lt;br /&gt;
LTspice is a high performance Spice III simulator, schematic capture and waveform viewer with enhancements and models for easing the simulation of switching regulators. Included in this download are Spice, Macro Models for 80% of Linear Technology&#039;s switching regulators, over 200 op amp models, as well as resistors, transistors and MOSFET models. &lt;br /&gt;
&lt;br /&gt;
[http://www.linear.com/designtools/software/switchercad.jsp Download LTspice]&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=PHYS321&amp;diff=2911</id>
		<title>PHYS321</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=PHYS321&amp;diff=2911"/>
		<updated>2024-06-10T08:56:50Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: /* Nettressurser */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Fagressurser for bruk i PHYS321 ==&lt;br /&gt;
&lt;br /&gt;
=== Fagbøker ===&lt;br /&gt;
* [http://site.ebrary.com/lib/bergen/docDetail.action?docID=10053265 Essentials of Electronic Testing for Digital, Memory, and Mixed-Signal VLSI Circuits]&lt;br /&gt;
&lt;br /&gt;
=== Nettressurser ===&lt;br /&gt;
* [http://www.ecs.umass.edu/ece/koren/arith/simulator/ Arithmetic Algorithms Simulators]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Linear_feedback_shift_register Linear feedback shift register]&lt;br /&gt;
* [https://robey.lag.net/2012/11/14/how-to-add-numbers-2.html How to add numbers (part 2)]&lt;br /&gt;
&lt;br /&gt;
==== Cadence tutorials ====&lt;br /&gt;
* [http://www-classes.usc.edu/engr/ee-s/477p/cadencetutorial.pdf Inverter eksempel]&lt;br /&gt;
* [https://www.youtube.com/watch?v=DPCu822wXPQ Inverter eksempel 1 youtube]&lt;br /&gt;
* [https://www.youtube.com/watch?v=AIjGRzNIWC4 Inverter eksempel 2 youtube]&lt;br /&gt;
* [https://www.youtube.com/watch?v=mQm88hoskkw Inverter eksempel 3 youtube]&lt;br /&gt;
&lt;br /&gt;
==== Digilent Nexys 4 ====&lt;br /&gt;
* [https://reference.digilentinc.com/vivado:installation Install Vivado with free licence]&lt;br /&gt;
* [https://reference.digilentinc.com/nexys:nexys4:gsg Getting started]&lt;br /&gt;
* [https://reference.digilentinc.com/vivado Vivado - Xilinx Programming Environment - Board files, reference projects, etc]&lt;br /&gt;
* [https://reference.digilentinc.com/nexys:nexys4:start Nexys 4 Resource center]&lt;br /&gt;
&lt;br /&gt;
==== Using Vivado ====&lt;br /&gt;
&lt;br /&gt;
* [[Install Vivado 2015.4 with free license]]&lt;br /&gt;
* [[VGA controller VHDL code]]&lt;br /&gt;
* [[Nexys4_Master.xdc]]&lt;br /&gt;
* [[Using the VGA controller with block ram generator and clock wizard]]&lt;br /&gt;
&lt;br /&gt;
=== Gamle øvingsoppgaver ===&lt;br /&gt;
[[Øvingsoppgaver PHYS321]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Transistor_operating_point_printer&amp;diff=2910</id>
		<title>Transistor operating point printer</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Transistor_operating_point_printer&amp;diff=2910"/>
		<updated>2024-05-30T11:56:01Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= DC operating parameters from simulation = &lt;br /&gt;
This script can be used to print the operating point parameters of all transistors in your design and save them to a file. &lt;br /&gt;
&lt;br /&gt;
If you just want to view them in Virtusoso have a look at this guide instead: [[DCoperatingparameters]]&lt;br /&gt;
&lt;br /&gt;
== Get the DC operating points from a previous simulation ==&lt;br /&gt;
Navigate to the folder you want to save the script in (this tutorial uses the home (./) directory) and create a new file in the terminal by entering &amp;lt;code&amp;gt; touch transistors.ocn &amp;lt;/code&amp;gt;. Open the file by writing &amp;lt;code&amp;gt; gedit transistors.ocn &amp;amp; &amp;lt;/code&amp;gt; and copy the following script into the document. Change ./transistors.csv in the script if you want another output file name and/or location. Save the file.&lt;br /&gt;
 selectResult(&#039;dcOpInfo)&lt;br /&gt;
 report(?output &amp;quot;./transistors.csv&amp;quot; ?param list(&amp;quot;gm&amp;quot; &amp;quot;gmb&amp;quot; &amp;quot;gmoverid&amp;quot; &amp;quot;gds&amp;quot; &amp;quot;id&amp;quot; &amp;quot;idsat&amp;quot; &amp;quot;vth&amp;quot; &amp;quot;region&amp;quot; &amp;quot;cgs&amp;quot; &amp;quot;cgd&amp;quot; &amp;quot;self_gain&amp;quot; &amp;quot;type&amp;quot; &amp;quot;vds&amp;quot; &amp;quot;vdsat&amp;quot; &amp;quot;vgs&amp;quot;) ?format &amp;quot;spice&amp;quot; ?maxLineWidth 1000)&lt;br /&gt;
 &lt;br /&gt;
 file = outfile(&amp;quot;./transistors.csv&amp;quot; &amp;quot;a&amp;quot;)&lt;br /&gt;
 fprintf(file &amp;quot;\n\nRegion 0 is cutoff.\nRegion 1 is linear.\nRegion 2 is saturation .\nRegion 3 is subthreshold.\nRegion 4 is breakdown.\n\nType 0 is nMOS. \nType 1 is pMOS.&amp;quot;)&lt;br /&gt;
 close(file)&lt;br /&gt;
&lt;br /&gt;
For the IHP design kit use:&lt;br /&gt;
 selectResult(&#039;dcOpInfo)&lt;br /&gt;
 report(?output &amp;quot;./transistors.csv&amp;quot; ?param list(&amp;quot;model&amp;quot; &amp;quot;gm&amp;quot; &amp;quot;gmb&amp;quot; &amp;quot;gds&amp;quot; &amp;quot;ids&amp;quot; &amp;quot;idsat&amp;quot; &amp;quot;vth&amp;quot; &amp;quot;region&amp;quot; &amp;quot;cgs&amp;quot; &amp;quot;cgd&amp;quot; &amp;quot;vds&amp;quot; &amp;quot;vsat&amp;quot; &amp;quot;vgs&amp;quot;) ?format &amp;quot;spice&amp;quot; ?maxLineWidth 1000)&lt;br /&gt;
 &lt;br /&gt;
 file = outfile(&amp;quot;./transistors.csv&amp;quot; &amp;quot;a&amp;quot;)&lt;br /&gt;
 fprintf(file &amp;quot;\n\nRegion 0 is cutoff.\nRegion 1 is linear.\nRegion 2 is saturation .\nRegion 3 is subthreshold.\nRegion 4 is breakdown.\n\nType 0 is nMOS. \nType 1 is pMOS.&amp;quot;)&lt;br /&gt;
 close(file)&lt;br /&gt;
&lt;br /&gt;
This script uses the results from the previous Debug Test (from ADE XL Test Editor). Before running the script, run a test with DC analysis, and remember to check the box with &amp;quot;Save DC Operating Point&amp;quot; :&lt;br /&gt;
&lt;br /&gt;
[[File:Run_debug_simulation.png | 500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After running DC analysis, run the script by entering the following into the Virtuoso Log Window (with file name and location as mentioned above): &amp;lt;code&amp;gt;load(&amp;quot;./transistors.ocn&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Run_transistors_script.png]]&lt;br /&gt;
&lt;br /&gt;
== Copy the file to your computer and convert the values == &lt;br /&gt;
After running the script, you can open the results file from the terminal using for example: &amp;lt;code&amp;gt; gedit transistors.csv &amp;amp; &amp;lt;/code&amp;gt; or alternatively to get the file out from the mikroserver you use to another computer try this: &lt;br /&gt;
&lt;br /&gt;
Create a file named &amp;quot;Makefile&amp;quot; and put this into it:&lt;br /&gt;
&lt;br /&gt;
 # target that is the first (and default) and does all the stuff below&lt;br /&gt;
 all: get fix clean &lt;br /&gt;
 &lt;br /&gt;
 # gets the file from your mikroserver and copies it to your computer in the root of your homefolder&lt;br /&gt;
 get :&lt;br /&gt;
        scp my_user_name@mikroserver:~/tsmc/transistors.csv ~/transistors_raw.csv        &lt;br /&gt;
 &lt;br /&gt;
 # converts transitors.csv to a copy where all the postfixes for the SI units generated from Virtuoso (m, f, K etc), has been replaced with E-3, E-15, E+3 etc, so the values are useable in LibreOffice&lt;br /&gt;
 fix :&lt;br /&gt;
        sed -e &#039;s/\([0-9]\+\)m/\1E-3/g&#039; -e &#039;s/\([0-9]\+\)u/\1E-6/g&#039; -e &#039;s/\([0-9]\+\)n/\1E-9/g&#039; -e &#039;s/\([0-9]\+\)p/\1E-12/g&#039; -e &#039;s/\([0-9]\+\)f/\1E-15/g&#039; -e &#039;s/\([0-9]\+\)a/\1E-18/g&#039; -e &#039;s/\([0-9]\+\)z/\1E-21/g&#039; -e &#039;s/\([0-9]\+\)y/\1E-24/g&#039; -e &#039;s/\([0-9]\+\)K/\1E+3/g&#039; -e &#039;s/\([0-9]\+\)M/\1E+6/g&#039; -e &#039;s/\([0-9]\+\)G/\1E+9/g&#039; -e &#039;s/\([0-9]\+\)T/\1E+12/g&#039; transistors_raw.csv &amp;gt; transistors.csv&lt;br /&gt;
 &lt;br /&gt;
 # removes the not-fixed copy&lt;br /&gt;
 clean: &lt;br /&gt;
        rm transistors_raw.csv&lt;br /&gt;
&lt;br /&gt;
Modify the scp-command to use&lt;br /&gt;
* The username and the correct mikroserver in the scp-command&lt;br /&gt;
* change the folder on mikroserver where the transistors.csv is created, default is /home/$user/tsmc/&lt;br /&gt;
* change the local folder where you want your copy to be placed, default is /home/$user/&lt;br /&gt;
&lt;br /&gt;
Now you can type &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; in the folder you created the Makefile and the latestst simulation data will appear in your homefolder.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Open the file in Libre Office == &lt;br /&gt;
The resulting transistors.csv can then be imported into LibreOffice Calc (similar to Microsoft Excel) using File-&amp;gt;Open, then choose the .csv file and enter the settings as in the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:Csv_import_libreoffice.png | 500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting == &lt;br /&gt;
For the scp-command to work without password you have to set up your connection as described in [[MikroserverSetup]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]] [[Category:Integrated_Circuts]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=TSMC_130nm_process&amp;diff=2909</id>
		<title>TSMC 130nm process</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=TSMC_130nm_process&amp;diff=2909"/>
		<updated>2024-05-30T11:54:37Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Cadence design with TSMC 130nm process=&lt;br /&gt;
This tutorial will start from very basics in analog IC design then take you through the whole analog IC design process.&lt;br /&gt;
&lt;br /&gt;
Here is the outline of the analog IC design flow:&lt;br /&gt;
# Schematic capture (Cadence tool)&lt;br /&gt;
# Netlist extraction from schematic&lt;br /&gt;
# Simulating using ELDO simulator and viewing results with EZWAVE (ELDO is a Mentor Graphic&#039;s tool for netlist level simulations)&lt;br /&gt;
# Layout using Cadence&lt;br /&gt;
# Signoff layout (DRC, LVS and parasitic extraction) using Calibre (Calibre is a Mentor Graphic&#039;s tool)&lt;br /&gt;
&lt;br /&gt;
==Setup of Cadence==&lt;br /&gt;
&lt;br /&gt;
To start virtuoso one must first connect to the chosen mikroserver&lt;br /&gt;
 ssh -X mikroserver&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;First&#039;&#039;&#039; time you should add the following line to your cds.lib-file by running this command: &lt;br /&gt;
 mkdir ~/tsmc&lt;br /&gt;
 echo &amp;quot;DEFINE tsmc13rf /eda/design_kits/tsmc_013/tsmc13rf&amp;quot; &amp;gt; ~/tsmc/cds.lib&lt;br /&gt;
&lt;br /&gt;
Then (&#039;&#039;&#039;each time&#039;&#039;&#039;) run these commands to set up Cadence&lt;br /&gt;
 source /eda/cadence/2023-24/scripts/analog_flow.sh&lt;br /&gt;
 source /eda/cadence/eda_general_init.sh&lt;br /&gt;
&lt;br /&gt;
Virtuoso Mixed Signal Design Environment is started by issuing this command:&lt;br /&gt;
 virtuoso &amp;amp;&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
* Make sure you source the script from the correct year. For example 2023-24 and not 2016-17&lt;br /&gt;
* Make sure you are connected the the right mikroserver&lt;br /&gt;
* Make sure you run virtuoso from the same folder as your &#039;cds.lib&#039;-folder (&#039;~/tsmc/&#039;)&lt;br /&gt;
&lt;br /&gt;
== Getting started ==&lt;br /&gt;
&lt;br /&gt;
In the log window, choose &amp;quot;File &amp;gt; New &amp;gt; Library&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
In the &amp;quot;New Library&amp;quot; dialog box, you must give the library a name (for example TORLIB, as I did). You must also specify a technology file. Here you choose &amp;quot;Attach to an existing technology library&amp;quot;. Then click the OK button. When asked for technology, choose &amp;quot;tsmc13rf&amp;quot;. If you are using IHP instead, choose &amp;quot;SG13_dev&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
After successfully creating the new library, it is time to create your first design. In the log window, choose &amp;quot;File &amp;gt; New &amp;gt; Cellview&amp;quot;. In the &amp;quot;Create New File&amp;quot; dialog box, you must give the design a name. You must also specify which library the design belongs to, and here you specify the library that you have just created. Choose to open the cell with &amp;quot;Schematics XL&amp;quot; and add a check-mark to always use this application if it is not checked.&lt;br /&gt;
&lt;br /&gt;
Now click OK, and the Virtuoso Schematic Editor should pop up. We will now draw a simple inverter design, as shown in the picture:&lt;br /&gt;
&lt;br /&gt;
[[File:virtuoso_schematic_editor.png|400px]]&lt;br /&gt;
&lt;br /&gt;
==Entering the design==&lt;br /&gt;
To create the inverter design, do the following:&lt;br /&gt;
&lt;br /&gt;
# Press &#039;i&#039; or click on the &amp;quot;Instance&amp;quot; icon to invoke the transistors. The &amp;quot;Add Instance&amp;quot; dialog box will now pop up. In the &amp;quot;Library&amp;quot; field, click &amp;quot;Browse&amp;quot; to open the &amp;quot;Library Browser&amp;quot;. In the library browser, choose &amp;quot;tsmc13rf&amp;quot; as library, &amp;quot;nmos3v&amp;quot; (for n-type transistor) or &amp;quot;pmos3v&amp;quot; (for p-type transistor) as cell and &amp;quot;spectre&amp;quot; as view. The cell is placed in the schematic by moving the cursor to the desired location and clicking the left mouse button.&lt;br /&gt;
# To insert the voltage sources, pick the &amp;quot;vdc&amp;quot; cell from the &amp;quot;analogLib&amp;quot; library. Add one connected to vdd and gnd and one connected to the input.&lt;br /&gt;
# To insert the ground and vdd nets, pick the &amp;quot;vdd&amp;quot; and &amp;quot;gnd&amp;quot; cells from the &amp;quot;analogLib&amp;quot; library. Here the view name should be &amp;quot;symbol&amp;quot;, not &amp;quot;spectreS&amp;quot; (in fact, &amp;quot;symbol&amp;quot; is the only available option).&lt;br /&gt;
# To connect the symbols, press &#039;w&#039; or click the &amp;quot;Wire (narrow)&amp;quot; icon. Then use the left mouse button to click the nodes togeter, two by two.&lt;br /&gt;
# To remove an instance or a wire, left click at the instance or wire that you want to remove, then press the &amp;quot;Delete&amp;quot; button on the keyboard.&lt;br /&gt;
# To insert a pin, press &#039;p&#039;. Choose a name for the pin in the dialog that occurs and click on the schematic to place it. Create one input and one output.&lt;br /&gt;
# To change the properties of the icons, press &#039;q&#039; or click at the &amp;quot;Properties&amp;quot; icon. Then click at the instances or nets that you want to modify. For the vdc source connected between vdd and gnd, set the &amp;quot;DC voltage&amp;quot; property to 3.3.&lt;br /&gt;
# To check and save the schematic, press &#039;x&#039; or click the &amp;quot;Check and save&amp;quot; icon. &lt;br /&gt;
# If there are any errors or warnings, press ok and press &#039;g&#039; or &amp;quot;Check-&amp;gt;Find Marker&amp;quot; to view the errors. Make sure you have no errors or warnings before continuing. &lt;br /&gt;
&lt;br /&gt;
==Simulating the design==&lt;br /&gt;
&lt;br /&gt;
# Open &amp;quot;Launch &amp;gt; ADE GXL&amp;quot; and press create new view. The &amp;quot;Virtuoso Analog Environment&amp;quot; should now come up.&lt;br /&gt;
# Choose &amp;quot;Create &amp;gt; Test...&amp;quot; select the cell to simulate.&lt;br /&gt;
# Choose &amp;quot;Outputs &amp;gt; To be plotted &amp;gt; Select on Schematic&amp;quot;. Click at the &amp;quot;in&amp;quot; node connected to the inverter input and the &amp;quot;out&amp;quot; node connected to the output.&lt;br /&gt;
# Choose &amp;quot;Analyses &amp;gt; Choose&amp;quot;. We will now run a dc analysis to obtain the DC transfer characteristics of the inverter. Choose &amp;quot;Component parameter&amp;quot; as your sweep variable. Then click at &amp;quot;Select component&amp;quot;. In the schematic, click at the input &amp;quot;vdc&amp;quot; instance. In the &amp;quot;Select Component Parameter&amp;quot; dialog box, choose dc as your sweep parameter. The sweep range should go from 0 to 3.3.&lt;br /&gt;
&lt;br /&gt;
[[File:select_comp_parameter.png|300px]]&lt;br /&gt;
&lt;br /&gt;
The analog environment should now look like this:&lt;br /&gt;
&lt;br /&gt;
[[File:analog_env_2.png|500px]]&lt;br /&gt;
&lt;br /&gt;
Switch to the &amp;quot;adexl&amp;quot; tab and choose the green run button. When the run is completed press the graph button beside the box that says &amp;quot;Replace&amp;quot;. The outputs should look like this:&lt;br /&gt;
[[File:plot_output_dc.png|600px]]&lt;br /&gt;
&lt;br /&gt;
To save your simulation settings, choose &amp;quot;Session &amp;gt; Save state&amp;quot; in the test editor windoe to save your state information under whatever file name you want. In a later session, you can reload your saved states using &amp;quot;Session &amp;gt; Load state&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Generating a Symbol==&lt;br /&gt;
Finally, we want to generate a symbol for our inverter. This symbol is needed if we want to use our inverter design inside another design (hierarchical design methodology). &lt;br /&gt;
&lt;br /&gt;
Select the schematic tab and choose &amp;quot;Create -&amp;gt; Create Cellview -&amp;gt; From Cellview&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Press OK in the dialog that occurs.&lt;br /&gt;
&lt;br /&gt;
The pins should already be connected to the right positions in the symbol generator, so press OK here also and ths symbol editor will occur.&lt;br /&gt;
&lt;br /&gt;
Press the red X and delete the pre-created green square. Use the line tool and the circle tool to create the inverter symbol&lt;br /&gt;
&lt;br /&gt;
[[File:symbol.png|400px]]&lt;br /&gt;
&lt;br /&gt;
Save it by clicking the &amp;quot;Save and check&amp;quot; symbol or pressing &#039;shift+X&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]] [[Category:Integrated_Circuts]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=MikroserverSetup&amp;diff=2908</id>
		<title>MikroserverSetup</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=MikroserverSetup&amp;diff=2908"/>
		<updated>2024-05-30T11:52:52Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Setup of connection to mikroservers= &lt;br /&gt;
&lt;br /&gt;
This setup process will allow you to connect to the mikroservers with one command without typing any password or long host names.&lt;br /&gt;
&lt;br /&gt;
== SSH key == &lt;br /&gt;
To login to the server without having to type in your password every time, we can use SSH key pairs. The public key is stored on the server, and you have your private key stored on the UiB login server.&lt;br /&gt;
&lt;br /&gt;
To generate a key, type into the terminal &lt;br /&gt;
 ssh-keygen  &lt;br /&gt;
This will generate the files id_rsa and id_rsa.pub in the folder ~/.ssh, where the latter is the public key that needs to be stored on the server. Copy the key with your identity to any of the mikroservers (since the user environment is shared for each server, this will give you access to all the servers). You can do this manually, but the easiest way is to use the ssh-copy-id utility. NB: Replace USERNAME with your username and mikroserver with the full name of your preferred mikroserver.&lt;br /&gt;
 ssh-copy-id USERNAME@mikroserver&lt;br /&gt;
You will be prompted your password. After the key is copied, you should be able to login with &amp;quot;ssh USERNAME@mikroserver&amp;quot; without having to enter your password. &lt;br /&gt;
&lt;br /&gt;
== Connection aliases ==&lt;br /&gt;
&lt;br /&gt;
Now that you can login without typing your password, it is also convenient to set up aliases for the servers to connect quicker.&lt;br /&gt;
&lt;br /&gt;
To do this, type &amp;quot;gedit ~/.ssh/config&amp;quot; in the terminal.&lt;br /&gt;
This will open up an empty file, and here you can store shorthand names and specific SSH settings for the connection, such as your username. &lt;br /&gt;
 Host mikroserver&lt;br /&gt;
     HostName mikroserver&lt;br /&gt;
     User USERNAME&lt;br /&gt;
     Port 22&lt;br /&gt;
     ForwardX11 yes&lt;br /&gt;
     ForwardX11Trusted yes&lt;br /&gt;
Copy and repeat this for each server in the same file, remembering to change the hostname to the full name of the corresponding mikroserver for each entry. ForwardX11 allows you to launch software on the server itself, while displaying the GUI remotely to the lab PC. &lt;br /&gt;
&lt;br /&gt;
After saving the file, you should be able to simply write &amp;quot;ssh mikroserver&amp;quot; in the terminal to login to the chosen mikroserver. &lt;br /&gt;
Note: If you are attempting to do this step remotely from the UiB login server you need to use a terminal-based editor like Vim, or connect to the login-server with &lt;br /&gt;
 ssh -Y USERNAME@login.uib.no&lt;br /&gt;
to enable the use of graphical editors such as gedit.&lt;br /&gt;
&lt;br /&gt;
== Automatic sourcing ==&lt;br /&gt;
There are two main files of sourcing scripts in a Linux environment. One is the file .bashrc, and the other is the file .profile. The difference in these is that the contents of .profile is executed upon login, and .bashrc is executed every time you access the terminal. .bashrc is not sourced to the system by itself upon login, so we need to source .bashrc in .profile manually to use it. This must be done after connecting to one of the mikroservers.&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;source ~/.bashrc&amp;quot; &amp;gt;&amp;gt; ~/.profile&lt;br /&gt;
&lt;br /&gt;
Scripts can be sourced either within .profile or .bashrc. This will make sure the scripts are loaded every time you log in, so you don&#039;t have to do it manually every time. &lt;br /&gt;
&lt;br /&gt;
== Accessing the lab software remotely on your private PC ==&lt;br /&gt;
You do not need to set up a VPN to access the lab software from home. By connecting to the mikroservers through the UiB loginserver with X11 forwarding enabled, you can run the software from any network. You can do this directly on Linux/macOS by using SSH in the bash terminal. For Windows, you will need to download the X server software [https://sourceforge.net/projects/xming/ Xming] to enable X11 forwarding. This install comes with PuTTY, an SSH client we will use to connect to the Linux based UiB server. &lt;br /&gt;
&lt;br /&gt;
=== Linux/macOS ===&lt;br /&gt;
The process is the same for both Linux and macOS, except that for macOS you first have to install the X11 server software named [https://www.xquartz.org/ XQuartz].&lt;br /&gt;
Then, simply connect to the login server by typing&lt;br /&gt;
 ssh -Y USERNAME@login.uib.no&lt;br /&gt;
&lt;br /&gt;
The -Y enables trusted X11 forwarding. From here, you can &amp;quot;ssh mikroserver&amp;quot; just as you would from the lab PC and run software. The steps described above (SSH keys and config files) can be repeated on your personal Linux/macOS PC to simplify connecting to the UiB loginserver. On Linux, the configuration file is located in &amp;quot;~/.ssh/config&amp;quot; just as on the server, while on macOS it is located in &amp;quot;/private/etc/ssh/ssh_config&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Windows ===&lt;br /&gt;
Install Xming and make sure you include PuTTY in the install. Run Xming. It will start minimized, and does not require any setup. &lt;br /&gt;
When first opening PuTTY, you will be presented with this configuration menu. Fill in the hostname &amp;quot;login.uib.no&amp;quot;, but don&#039;t connect yet.&lt;br /&gt;
 [[File:Puttylogin.png]]&lt;br /&gt;
Navigate to Connection -&amp;gt; SSH -&amp;gt; X11, and check Enable X11 forwarding, and type in &amp;quot;localhost:0.0&amp;quot; as X display location.&lt;br /&gt;
 [[File:Puttyx11.png]]&lt;br /&gt;
Return to Session, and make sure connection type is set to SSH. Press &amp;quot;Default Settings&amp;quot; and Save to save this configuration for later. Press Open to connect to the server. Enter your username and password, and now you should be in the Linux terminal for the UiB login server. Try to run &amp;quot;gedit&amp;quot; to confirm that you can run a graphical interface. From here you can ssh to the mikroservers and launch software as on the lab computer. Confirm by running gedit on the mikroserver as well to see that you can tunnel X11 through the login server correctly. &lt;br /&gt;
&lt;br /&gt;
== Add mikroserver as a folder on your pc ==&lt;br /&gt;
&lt;br /&gt;
Open up your home folder in Linux and in the bottom left  corner click &amp;quot;Connect to Server&amp;quot; as shown in this picture:&lt;br /&gt;
[[File:ConnectToServer.png|thumbnail]]&lt;br /&gt;
&lt;br /&gt;
as server address type:&lt;br /&gt;
 [sftp://mikroserver3/home/USERNAME sftp://mikroserver/home/USERNAME]&lt;br /&gt;
to add your homefolder on mikroserver as a folder on your local PC for easy access to your files (for example the [[Transistor_operating_point_printer]])&lt;br /&gt;
To store this connection, right click the &amp;quot;mikroserver&amp;quot;-folder and click &amp;quot;Add Bookmark&amp;quot;. The next time you just click the bookmark to open it.&lt;br /&gt;
&lt;br /&gt;
=== Alternative way using scp/secure copy===&lt;br /&gt;
If for some reason the above doesn’t work you can try this:&lt;br /&gt;
* connect to your mikroserver&lt;br /&gt;
* locate the file you want to copy. i.e /home/USERNAME/picture.jpg&lt;br /&gt;
* type this command&lt;br /&gt;
 scp picture.jpg USERNAME@login.uib.no:path/to/folder/to/copy/to&lt;br /&gt;
* this will copy the file to your home folder on any UiB machine&lt;br /&gt;
* To copy a folder&lt;br /&gt;
 scp -r NameOfFolder USERNAME@login.uib.no:path/to/folder/to/copy/to&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting == &lt;br /&gt;
* Make sure you have restarted your terminal (or source ~/.bashrc) if the commands doesn&#039;t work&lt;br /&gt;
* You have to be either connected to the UiB loginserver or run the commands via the computers in the lab to be able to connect to the mikroservers&lt;br /&gt;
* If you are using another shell like zsh or csh the aliases has to be in ~/.zshrc or  ~/.cshrc instead of ~/.bashrc&lt;br /&gt;
* Make sure you have replaced all the instances of USERNAME with your usename, i.e &amp;quot;abc0123&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=IHP_130nm_process&amp;diff=2907</id>
		<title>IHP 130nm process</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=IHP_130nm_process&amp;diff=2907"/>
		<updated>2024-05-30T11:47:50Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Cadence design with IHP 130nm process=&lt;br /&gt;
&lt;br /&gt;
==Starting up the IHP SG13S Design Kit==&lt;br /&gt;
&lt;br /&gt;
The following steps describe how to install the Process Design Kit and start a new design. &lt;br /&gt;
&lt;br /&gt;
Log on to the mikroserver of choise&lt;br /&gt;
 ssh -X mikroserver&lt;br /&gt;
&lt;br /&gt;
The preferred shell is bash. When using another shell it will be necessary to change the installation routine and modify the initialization script accordingly.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;first time&#039;&#039;&#039; you are using the IHP design kit you should copy the user environment design to your chosen parent directory (e.g ~/ihp)&lt;br /&gt;
 cp -rp /eda/design_kits/ihp_sg13/SG13S_618_rev1.12.0/work/skel ~/ihp&lt;br /&gt;
&lt;br /&gt;
Change sh.cadence in ~/ihp/cds to suit your needs. In particular you must define $IHP_TECH and $PROJECT according to your local environment. Then set general and user Cadence environment variables by doing:&lt;br /&gt;
 source /eda/design_kits/ihp_sg13/sh.cadence&lt;br /&gt;
 cd ~/ihp/cds/&lt;br /&gt;
 source /eda/design_kits/ihp_sg13/sh.cadence&lt;br /&gt;
To start Cadence Virtuoso : virtuoso &amp;amp;&lt;br /&gt;
&lt;br /&gt;
Example script [[:File:example_script.txt]] to run from_ &amp;quot;user&amp;quot;/ihp/cds/&lt;br /&gt;
&lt;br /&gt;
To avoid having to do this every time try to set up your environment like described in [[MikroserverSetup]]&lt;br /&gt;
&lt;br /&gt;
= Before starting designing =&lt;br /&gt;
&lt;br /&gt;
Read the Design Kit User Guide. It can be found on the SG13SFeatures tab on the Virtuoso console window, or in the folder &amp;quot;/eda/design_kits/ihp_sg13/SG13S_618_rev1.12.0/doc/pdf/&amp;quot; on the mikroserver. Make sure that your web browser is closed or started from the mikroserver, else the file will not be found.&lt;br /&gt;
&lt;br /&gt;
Other documents are found in &amp;quot;eda/design_kits/ihp_sg13/SG13S_618_rev1.12.0/doc/html/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]] [[Category:Integrated_Circuts]] [[Category:Cadence_Virtuoso]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Transistor_operating_point_printer&amp;diff=2906</id>
		<title>Transistor operating point printer</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Transistor_operating_point_printer&amp;diff=2906"/>
		<updated>2024-05-30T11:46:04Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= DC operating parameters from simulation = &lt;br /&gt;
This script can be used to print the operating point parameters of all transistors in your design and save them to a file. &lt;br /&gt;
&lt;br /&gt;
If you just want to view them in Virtusoso have a look at this guide instead: [[DCoperatingparameters]]&lt;br /&gt;
&lt;br /&gt;
== Get the DC operating points from a previous simulation ==&lt;br /&gt;
Navigate to the folder you want to save the script in (this tutorial uses the home (./) directory) and create a new file in the terminal by entering &amp;lt;code&amp;gt; touch transistors.ocn &amp;lt;/code&amp;gt;. Open the file by writing &amp;lt;code&amp;gt; gedit transistors.ocn &amp;amp; &amp;lt;/code&amp;gt; and copy the following script into the document. Change ./transistors.csv in the script if you want another output file name and/or location. Save the file.&lt;br /&gt;
 selectResult(&#039;dcOpInfo)&lt;br /&gt;
 report(?output &amp;quot;./transistors.csv&amp;quot; ?param list(&amp;quot;gm&amp;quot; &amp;quot;gmb&amp;quot; &amp;quot;gmoverid&amp;quot; &amp;quot;gds&amp;quot; &amp;quot;id&amp;quot; &amp;quot;idsat&amp;quot; &amp;quot;vth&amp;quot; &amp;quot;region&amp;quot; &amp;quot;cgs&amp;quot; &amp;quot;cgd&amp;quot; &amp;quot;self_gain&amp;quot; &amp;quot;type&amp;quot; &amp;quot;vds&amp;quot; &amp;quot;vdsat&amp;quot; &amp;quot;vgs&amp;quot;) ?format &amp;quot;spice&amp;quot; ?maxLineWidth 1000)&lt;br /&gt;
 &lt;br /&gt;
 file = outfile(&amp;quot;./transistors.csv&amp;quot; &amp;quot;a&amp;quot;)&lt;br /&gt;
 fprintf(file &amp;quot;\n\nRegion 0 is cutoff.\nRegion 1 is linear.\nRegion 2 is saturation .\nRegion 3 is subthreshold.\nRegion 4 is breakdown.\n\nType 0 is nMOS. \nType 1 is pMOS.&amp;quot;)&lt;br /&gt;
 close(file)&lt;br /&gt;
&lt;br /&gt;
For the IHP design kit use:&lt;br /&gt;
 selectResult(&#039;dcOpInfo)&lt;br /&gt;
 report(?output &amp;quot;./transistors.csv&amp;quot; ?param list(&amp;quot;model&amp;quot; &amp;quot;gm&amp;quot; &amp;quot;gmb&amp;quot; &amp;quot;gds&amp;quot; &amp;quot;ids&amp;quot; &amp;quot;idsat&amp;quot; &amp;quot;vth&amp;quot; &amp;quot;region&amp;quot; &amp;quot;cgs&amp;quot; &amp;quot;cgd&amp;quot; &amp;quot;vds&amp;quot; &amp;quot;vsat&amp;quot; &amp;quot;vgs&amp;quot;) ?format &amp;quot;spice&amp;quot; ?maxLineWidth 1000)&lt;br /&gt;
 &lt;br /&gt;
 file = outfile(&amp;quot;./transistors.csv&amp;quot; &amp;quot;a&amp;quot;)&lt;br /&gt;
 fprintf(file &amp;quot;\n\nRegion 0 is cutoff.\nRegion 1 is linear.\nRegion 2 is saturation .\nRegion 3 is subthreshold.\nRegion 4 is breakdown.\n\nType 0 is nMOS. \nType 1 is pMOS.&amp;quot;)&lt;br /&gt;
 close(file)&lt;br /&gt;
&lt;br /&gt;
This script uses the results from the previous Debug Test (from ADE XL Test Editor). Before running the script, run a test with DC analysis, and remember to check the box with &amp;quot;Save DC Operating Point&amp;quot; :&lt;br /&gt;
&lt;br /&gt;
[[File:Run_debug_simulation.png | 500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After running DC analysis, run the script by entering the following into the Virtuoso Log Window (with file name and location as mentioned above): &amp;lt;code&amp;gt;load(&amp;quot;./transistors.ocn&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Run_transistors_script.png]]&lt;br /&gt;
&lt;br /&gt;
== Copy the file to your computer and convert the values == &lt;br /&gt;
After running the script, you can open the results file from the terminal using for example: &amp;lt;code&amp;gt; gedit transistors.csv &amp;amp; &amp;lt;/code&amp;gt; or alternatively to get the file out from mikroserver &lt;br /&gt;
to another computer try this: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create a file named &amp;quot;Makefile&amp;quot; and put this into it:&lt;br /&gt;
&lt;br /&gt;
 # target that is the first (and default) and does all the stuff below&lt;br /&gt;
 all: get fix clean &lt;br /&gt;
 &lt;br /&gt;
 # gets the file from mikroserver3 and copies it to your computer in the root of your homefolder&lt;br /&gt;
 get :&lt;br /&gt;
        scp my_user_name@mikroserver:~/tsmc/transistors.csv ~/transistors_raw.csv        &lt;br /&gt;
 &lt;br /&gt;
 # converts transitors.csv to a copy where all the postfixes for the SI units generated from Virtuoso (m, f, K etc), has been replaced with E-3, E-15, E+3 etc, so the values are useable in LibreOffice&lt;br /&gt;
 fix :&lt;br /&gt;
        sed -e &#039;s/\([0-9]\+\)m/\1E-3/g&#039; -e &#039;s/\([0-9]\+\)u/\1E-6/g&#039; -e &#039;s/\([0-9]\+\)n/\1E-9/g&#039; -e &#039;s/\([0-9]\+\)p/\1E-12/g&#039; -e &#039;s/\([0-9]\+\)f/\1E-15/g&#039; -e &#039;s/\([0-9]\+\)a/\1E-18/g&#039; -e &#039;s/\([0-9]\+\)z/\1E-21/g&#039; -e &#039;s/\([0-9]\+\)y/\1E-24/g&#039; -e &#039;s/\([0-9]\+\)K/\1E+3/g&#039; -e &#039;s/\([0-9]\+\)M/\1E+6/g&#039; -e &#039;s/\([0-9]\+\)G/\1E+9/g&#039; -e &#039;s/\([0-9]\+\)T/\1E+12/g&#039; transistors_raw.csv &amp;gt; transistors.csv&lt;br /&gt;
 &lt;br /&gt;
 # removes the not-fixed copy&lt;br /&gt;
 clean: &lt;br /&gt;
        rm transistors_raw.csv&lt;br /&gt;
&lt;br /&gt;
Modify the scp-command to use&lt;br /&gt;
* The username and the correct microserver in the scp-command&lt;br /&gt;
* change the folder on mikroserver where the transistors.csv is created, default is /home/$user/tsmc/&lt;br /&gt;
* change the local folder where you want your copy to be placed, default is /home/$user/&lt;br /&gt;
&lt;br /&gt;
Now you can type &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; in the folder you created the Makefile and the latestst simulation data will appear in your homefolder.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Open the file in Libre Office == &lt;br /&gt;
The resulting transistors.csv can then be imported into LibreOffice Calc (similar to Microsoft Excel) using File-&amp;gt;Open, then choose the .csv file and enter the settings as in the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:Csv_import_libreoffice.png | 500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting == &lt;br /&gt;
For the scp-command to work without password you have to set up your connection as described in [[MikroserverSetup]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]] [[Category:Integrated_Circuts]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2905</id>
		<title>Synthese av VHDL</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2905"/>
		<updated>2024-05-30T11:43:00Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Syntetiseringen av VHDL kode===&lt;br /&gt;
&lt;br /&gt;
Grunnen til at vi skal syntetisere koden, er at vi må lage beskrivelse av koden tilpassa ein krets.&lt;br /&gt;
&lt;br /&gt;
Vi vil no prøve å synthesisere vhdl kode. Og etterpå vil vi lage ein testbenk der vi samanliknar utsignala frå den syntetiserte og den opprinnelige koden. Vi bruker ein alu som eksempel.&lt;br /&gt;
&lt;br /&gt;
==Precision==&lt;br /&gt;
&lt;br /&gt;
Precision bruker Vivado til å syntetisere vhdl-koden. For å starte synteseprogrammet:&lt;br /&gt;
&lt;br /&gt;
 export LM_LICENSE_FILE=27001@lisensserver1:29000@lisensserver2&lt;br /&gt;
 source /eda/Siemens/2023-24/scripts/PRECISION_2023.2_RHELx86.sh&lt;br /&gt;
 precision&lt;br /&gt;
&lt;br /&gt;
Erstatt lisensserver med rett navn på lisensserver (se &amp;quot;Micro-how-to&amp;quot; i mikroelektronikk-teamet).Nye versjoner av programvaren ligger i /eda/Siemens sortert på årstall.&lt;br /&gt;
&lt;br /&gt;
Velg deretter New Project, og deretter Add input file (i dette tilfelle add_sub_alu.vhd).&lt;br /&gt;
Så går vi inn på Setup design, velger ein kretsprodusent, den ønska kretsen og designfrekvens, for eksempel Zynq med frekvens 200MHz. For å få ut en vhdl fil av den syntetiserte koden må en gå på Tools-&amp;gt;Options-&amp;gt;Output og hak av for VHDL og trykk ok.&lt;br /&gt;
&lt;br /&gt;
Pass på at Precision finner Vivado, settes i menyen:&lt;br /&gt;
 Tools &amp;gt; Options &amp;gt; Place and Route Settings&lt;br /&gt;
deretter&lt;br /&gt;
 Vivado &amp;gt; Integrated Place and Route &amp;gt; path to Xilinx Vivado installation tree&lt;br /&gt;
settes til&lt;br /&gt;
 /eda/xilinx/Vivado/2020.2&lt;br /&gt;
&lt;br /&gt;
Trykk så compile, og synthesize. &lt;br /&gt;
No kan vi sjå på den generte kretsen i RTL Schematic og Technology Schematic (syntese med den valgte kretsen) under Schematics på venstre side.&lt;br /&gt;
&lt;br /&gt;
==Questasim==&lt;br /&gt;
&lt;br /&gt;
Start opp Questasim, lag nytt prosjekt og legg til vhdl fila (add_sub_alu.vhdl). Så legg vi til fila som Precision generte i prosjektdir til &#039;precision/prosjektnavn_temp_1/prosjektnavn.vhd&#039; (i vårt tilfelle &#039;alu/add_sub_alu_temp_1/add_sub_alu.vhd&#039;).&lt;br /&gt;
&lt;br /&gt;
Vi trenger simuleringsbibliotek for den valgte kretsfamilien for å kunne simulere etter &amp;quot;Place and Route&amp;quot;. Disse bibliotekene kan genereres fra Vivado med menyen&lt;br /&gt;
 Tools &amp;gt; Compile Simulation Libraries&lt;br /&gt;
men, vi har kompilert disse unisim-bibliotekene til mappen /eda/xilinx/lib. Du kan &amp;quot;mappe&amp;quot; disse slik:&lt;br /&gt;
&lt;br /&gt;
 vmap unisim /eda/xilinx/lib/unisim&lt;br /&gt;
 &lt;br /&gt;
Deretter legger vi til ei ny vhdl fil der vi skal lage testbenken vår. Vi legger til ein komponent av den opprinnelige og den synthesiserte vhdl koden. Vi koblar alle inngangane til samme signal på testbenken, og gir ut 2 forskjellige utsignal for å samanlikne ved hjelp av assert(sjå fila alu_tb.vhdl). På grunn av at utsignala av dei to komponentane ikkje skifta heilt synkront, testa vi berre kvart nanosekund ved å putta assert inn i ein process med wait for 1ns:&lt;br /&gt;
&lt;br /&gt;
 test : process&lt;br /&gt;
 begin&lt;br /&gt;
 wait for 1 ns;&lt;br /&gt;
 assert (data_out = data_out_synt)&lt;br /&gt;
 report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
 severity Error;&lt;br /&gt;
 end process test;&lt;br /&gt;
&lt;br /&gt;
Når vi har laga testbenken, kompilerer vi filene (husk å kompilere i rett rekkefølge med compileorder-&amp;gt;autogenerate første gong).&lt;br /&gt;
&lt;br /&gt;
Siden precision generer samme navn på entityen og architecturen på den syntetiserte filen som i den orginale så vil ikke simulatoren kjøre de samtidig. Dette endres ved å endre entity fra add_sub_alu til add_sub_alu_synth og skifte navnet på architecture fra algoritm til structure øverst og nederst i den syntetiserte filen.&lt;br /&gt;
&lt;br /&gt;
==Simulering med timing==&lt;br /&gt;
&lt;br /&gt;
Eksempel på start av simulering med timing:&lt;br /&gt;
&lt;br /&gt;
 vsim -t ps -sdfnoerror -sdfmax /alu_synth=/home/kaf003/VHDL_Prosjekter/PHYS321/vivado_impl_1/add_sub_alu_synth.sdf work.alu_tb&lt;br /&gt;
&lt;br /&gt;
Vi kan sjå at i dei første 50 nanosekunda er utsignala ulike. Dette er fordi før første klokkeflanke er verdiane udefinert i den opprinnelige komponenten, medan den synthesisere ikkje kan ha udefinerte verdiar. I Questasim vil vi derfor få ein del feilmeldingar dei første 50 nanosekunda.&lt;br /&gt;
&lt;br /&gt;
==Konklusjon==&lt;br /&gt;
&lt;br /&gt;
Vi kan teste om den syntesiserte komponenten oppfører seg likt med den opprinnelige komponenten ved å koble begge to til samme testbenk. Vi fekk problem i overgangane når vi testa kontinuerlig, så vi løyste problemet ved å berre teste kvart naonosekund. Bortsett frå dei første 50 nanosekunda (sjå grunn over) kan vi sjå at begge komponetane gir ut samme utsignal. Vi prøvde å bruke samme enitynavn på begge komponentane med ulik arcitechture, men fekk berre lov å kompilere og ikkje simulere. Vi kan derfor konkludere med at desse må ha ulike navn.&lt;br /&gt;
&lt;br /&gt;
==Kode==&lt;br /&gt;
&lt;br /&gt;
===Kode til add_sub_alu.vhd===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.All;&lt;br /&gt;
USE ieee.std_logic_unsigned.all;&lt;br /&gt;
&lt;br /&gt;
ENTITY add_sub_alu IS&lt;br /&gt;
PORT (&lt;br /&gt;
  clk         : IN  std_logic;&lt;br /&gt;
  rst         : IN  std_logic;&lt;br /&gt;
  enable_in   : IN  std_logic;&lt;br /&gt;
  start       : IN  std_logic;&lt;br /&gt;
  enable      : IN  std_logic;&lt;br /&gt;
  do_add      : IN  std_logic;&lt;br /&gt;
  do_subtract : IN  std_logic;&lt;br /&gt;
  do_hold     : IN  std_logic;&lt;br /&gt;
  data_in     : IN  std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  data_out    : OUT std_logic_vector(3 DOWNTO 0) BUS);&lt;br /&gt;
END add_sub_alu;&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE algorithm OF add_sub_alu IS&lt;br /&gt;
  TYPE   states          IS (hold, reset, add, subtract);&lt;br /&gt;
  SIGNAL state_var       : states;&lt;br /&gt;
  SIGNAL reg, int_reg    : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  SIGNAL latched_data_in : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
BEGIN&lt;br /&gt;
&lt;br /&gt;
latch: PROCESS (enable_in, data_in)is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (enable_in = &#039;1&#039;) THEN&lt;br /&gt;
    latched_data_in &amp;lt;= data_in;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS latch;&lt;br /&gt;
&lt;br /&gt;
fsm: PROCESS (clk, rst) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (rst = &#039;0&#039;) THEN&lt;br /&gt;
    state_var &amp;lt;= reset;&lt;br /&gt;
  ELSIF rising_edge(clk) THEN&lt;br /&gt;
    CASE state_var IS&lt;br /&gt;
      WHEN hold =&amp;gt;&lt;br /&gt;
        IF (start = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= reset;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN reset    =&amp;gt;&lt;br /&gt;
        IF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN add      =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN subtract =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN OTHERS =&amp;gt; state_var &amp;lt;= reset;&lt;br /&gt;
    END CASE;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS fsm;&lt;br /&gt;
&lt;br /&gt;
alu: PROCESS (state_var, latched_data_in, reg)is&lt;br /&gt;
BEGIN&lt;br /&gt;
CASE state_var IS&lt;br /&gt;
  WHEN add      =&amp;gt; int_reg &amp;lt;= reg + latched_data_in;&lt;br /&gt;
  WHEN subtract =&amp;gt; int_reg &amp;lt;= reg - latched_data_in;&lt;br /&gt;
  WHEN reset    =&amp;gt; int_reg &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
  WHEN hold     =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
  WHEN OTHERS   =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
END CASE;&lt;br /&gt;
END PROCESS alu;&lt;br /&gt;
&lt;br /&gt;
mem: PROCESS (clk) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF rising_edge(clk) THEN&lt;br /&gt;
    reg &amp;lt;= int_reg;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS mem;&lt;br /&gt;
&lt;br /&gt;
tri: PROCESS (enable, reg) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  FOR i IN 3 DOWNTO 0 LOOP&lt;br /&gt;
    IF (enable = &#039;1&#039;) THEN&lt;br /&gt;
      data_out(i) &amp;lt;= reg(i);&lt;br /&gt;
    ELSE&lt;br /&gt;
      data_out(i) &amp;lt;= &#039;Z&#039;;&lt;br /&gt;
    END IF;&lt;br /&gt;
  END LOOP;&lt;br /&gt;
END PROCESS tri;&lt;br /&gt;
&lt;br /&gt;
END algorithm;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Koden til alu_tb.vhdl===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library ieee;&lt;br /&gt;
use ieee.std_logic_1164.all;&lt;br /&gt;
library work;&lt;br /&gt;
use work.all;&lt;br /&gt;
&lt;br /&gt;
entity alu_tb is&lt;br /&gt;
end entity alu_tb;&lt;br /&gt;
&lt;br /&gt;
architecture struct of alu_tb is&lt;br /&gt;
  --Deklaring av signal som skal koblast til komponentane.&lt;br /&gt;
  --Alle innsignal er felles, medan vi har 2 forskjellige utsignal.&lt;br /&gt;
  signal clk           : std_logic;&lt;br /&gt;
  signal reset         : std_logic;&lt;br /&gt;
  signal enable_in     : std_logic;&lt;br /&gt;
  signal start         : std_logic;&lt;br /&gt;
  signal enable        : std_logic;&lt;br /&gt;
  signal do_add        : std_logic;&lt;br /&gt;
  signal do_subtract   : std_logic;&lt;br /&gt;
  signal do_hold       : std_logic;&lt;br /&gt;
  signal data_in       : std_logic_vector(3 downto 0);&lt;br /&gt;
  signal data_out      : std_logic_vector(3 downto 0);&lt;br /&gt;
  signal data_out_synt : std_logic_vector(3 downto 0);&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
  --Deklarer komponenten alu.&lt;br /&gt;
  alu : entity add_sub_alu(algorithm)&lt;br /&gt;
    --Kobler signala til den opprinnelige komponenten.&lt;br /&gt;
    port map (&lt;br /&gt;
    clk =&amp;gt; clk,&lt;br /&gt;
    rst =&amp;gt; reset,&lt;br /&gt;
    enable_in =&amp;gt; enable_in,&lt;br /&gt;
    start =&amp;gt; start,&lt;br /&gt;
    enable =&amp;gt; enable,&lt;br /&gt;
    do_add =&amp;gt; do_add,&lt;br /&gt;
    do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
    do_hold =&amp;gt; do_hold,&lt;br /&gt;
    data_in =&amp;gt; data_in,&lt;br /&gt;
    data_out =&amp;gt; data_out);&lt;br /&gt;
&lt;br /&gt;
  --Deklarer komponenten alu_synt.&lt;br /&gt;
  alu_synt : entity add_sub_alu_synth(structure)&lt;br /&gt;
  --Kobler signala til den synthiserte komponenten.&lt;br /&gt;
    port map (&lt;br /&gt;
    clk =&amp;gt; clk,&lt;br /&gt;
    rst =&amp;gt; reset,&lt;br /&gt;
    enable_in =&amp;gt; enable_in,&lt;br /&gt;
    start =&amp;gt; start,&lt;br /&gt;
    enable =&amp;gt; enable,&lt;br /&gt;
    do_add =&amp;gt; do_add,&lt;br /&gt;
    do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
    do_hold =&amp;gt; do_hold,&lt;br /&gt;
    data_in =&amp;gt; data_in,&lt;br /&gt;
    data_out =&amp;gt; data_out_synt);&lt;br /&gt;
&lt;br /&gt;
  --Klokkegenerator&lt;br /&gt;
  clock_gen : process&lt;br /&gt;
    begin&lt;br /&gt;
    clk &amp;lt;= &#039;0&#039;, &#039;1&#039; after 50 ns;&lt;br /&gt;
    wait for 100 ns;&lt;br /&gt;
  end process clock_gen;&lt;br /&gt;
&lt;br /&gt;
  --Setter testvektorane.&lt;br /&gt;
  reset &amp;lt;= &#039;0&#039;, &#039;1&#039; after 60 ns;&lt;br /&gt;
  enable &amp;lt;= &#039;1&#039;, &#039;0&#039; after 900 ns;&lt;br /&gt;
  enable_in &amp;lt;= &#039;1&#039;, &#039;0&#039; after 400 ns;&lt;br /&gt;
  start &amp;lt;= &#039;1&#039;, &#039;0&#039; after 300 ns;&lt;br /&gt;
  do_add &amp;lt;= &#039;1&#039;, &#039;0&#039; after 660 ns;&lt;br /&gt;
  do_subtract &amp;lt;= &#039;0&#039;;&lt;br /&gt;
  do_hold &amp;lt;= &#039;0&#039;;&lt;br /&gt;
  data_in &amp;lt;= X&amp;quot;3&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  --Test process for å samanlikne utsignala kvart nanosekund.&lt;br /&gt;
  test : process&lt;br /&gt;
  begin&lt;br /&gt;
  wait for 1 ns;&lt;br /&gt;
  assert (data_out = data_out_synt)&lt;br /&gt;
  report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
  severity Error;&lt;br /&gt;
  end process test;&lt;br /&gt;
&lt;br /&gt;
end architecture struct;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Simulering_av_VHDL&amp;diff=2904</id>
		<title>Simulering av VHDL</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Simulering_av_VHDL&amp;diff=2904"/>
		<updated>2024-05-30T11:39:53Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Konstruksjon og simulering av VHDL-kode med Modelsim/Questa===&lt;br /&gt;
&lt;br /&gt;
==Innledning==&lt;br /&gt;
&lt;br /&gt;
Hensikten med denne oppgaven er å få et lite innblikk i bruk av høynivåspråk for simulering og uttesting av kretsløsninger. I denne oppgaven skal vi bruker VHDL (Very high speed integrated circuit Hardware Description Language), som er spesielt utviklet for elektronikk. VHDL er definert slik at det passer i en mengde sammenhenger, og er det vil derfor være uoverkommelig å gå inn på detaljer i denne oppgaven. Vi skal ta for oss noen eksempler:&lt;br /&gt;
&lt;br /&gt;
* Eksempel 1: Signalflyt i en SR-lås&lt;br /&gt;
&lt;br /&gt;
* Eksempel 2: Signaler og variable&lt;br /&gt;
&lt;br /&gt;
Et VHDL program består i hovedsak av ENTITY, som definerer tilkobling mellom programmet og omverden, og ARCHITECTURE, som definerer programmets funksjon. Den komplette VHDL-koden for eksempel 1 vist nederst på denne siden.Mentor Graphics har utviklet programvare (Modelsim//Questa) som gjør det mulig å beskrivem, simulere og feilsøke VHDL-kode. Fremgangsmåten for skriving, kompilering og simulering av VHDL-kode finner du under.&lt;br /&gt;
&lt;br /&gt;
==Starte Questa Sim==&lt;br /&gt;
Når man skal arbeide med Questa Sim fra Mentor Graphics skriv følgende kommando i et terminalvindu.&lt;br /&gt;
Generelt ligger programvaren i /eda/Siemens, og versjonene ligger i mapper sortert på årstall.&lt;br /&gt;
&lt;br /&gt;
 ssh -X mikroserver4&lt;br /&gt;
 export LM_LICENSE_FILE=&amp;quot;Sett inn rett lisensserver og port her&amp;quot;&lt;br /&gt;
 source /eda/Siemens/2023-24/scripts/QUESTA-CORE-PRIME_2023.4_RHELx86.sh&lt;br /&gt;
 vsim&lt;br /&gt;
&lt;br /&gt;
==Lage et nytt prosjekt==&lt;br /&gt;
&lt;br /&gt;
I den følgende teksten er det vist hvordan man kan utføre kompilering, etc. på kommandolinjen. Dette kan enten gjøres i fra X terminalvinduet, eller fra kommandolinjen i Questa. Hvis man velger å bruke Questa-miljøet er de fleste prosedyrer/kommandoer tilgjengelige under menyen.&lt;br /&gt;
&lt;br /&gt;
Start et nytt prosjekt med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
File &amp;gt; New &amp;gt; Project&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:questa_new_project.png]]&lt;br /&gt;
&lt;br /&gt;
Velg et fornuftig navn og katalog. Man kan gjerne ha flere uavhengige vhdl-filer i et prosjekt.&lt;br /&gt;
Det er en fordel å ha en hovedkatalog til vhdl prosjektene og en underkatalog for prosjektet fex /home/bruker/vhdl_prosjekt/sr_latch&lt;br /&gt;
&lt;br /&gt;
==Skriving av VHDL kode==&lt;br /&gt;
&lt;br /&gt;
En ny VHDL kode (et design beskrevet med VHDL kode) påbegynnes med å starte emacs i terminal vinduet eller ved å bruke den innebygde teksteditoren i Questa ved å velge Create New File. &lt;br /&gt;
&lt;br /&gt;
Det fine med emacs er at man kan velge VHDL-modus. Dette gjøres med å skrive &#039;&#039;M-x vhdl-mode&#039;&#039; (M står for &#039;&#039;Meta&#039;&#039; og er vanligvis definert som esc-knappen). I emacs har en menyer med alle valg oppe langs kanten som i andre teksteditorer, men programmet skiller seg litt ut med kommandolinjen nederst i vinduet. Når en f. eks. skal lagre filen en har skrevet blir denne kommandolinjen aktiv og en skriver inn sti og filnavn der. Når man lagrer er ikke navnet på kodefilen viktig, men det er fornuftig å kalle den det samme som ENTITY-delen, med &#039;&#039;.vhdl&#039;&#039; som &amp;quot;etternavn&amp;quot; (f. eks. sr_latch.vhdl).&lt;br /&gt;
&lt;br /&gt;
==Kompilering av VHDL kode==&lt;br /&gt;
&lt;br /&gt;
Koden kompileres med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vcom sr_latch.vhdl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hvis det er feil i koden vil det komme en melding i kommando vinduet. Dobbeltklikker du på feilen vil du få opp en liste over kompileringsprosessen og alle feilene. Dobbeltklikker du så på linjen som angir en feil så vises den respektive linjen i editoren.&lt;br /&gt;
&lt;br /&gt;
Merk at navnet til det kompilerte designet blir skrevet med små bokstaver, selv om du har brukt store bokstaver i ENTITY- eller ARCHITECTURE-navnet. Det kompilerte designet blir liggende i work-katalogen.&lt;br /&gt;
&lt;br /&gt;
==Simulering og debugging i Questa==&lt;br /&gt;
&lt;br /&gt;
Når koden kompilerer feilfritt kan den simuleres i Questa. Dette startes med:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vsim&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nå dukker det opp en rute der du skal velge hva som skal simuleres, utvid work og velg vhdl filen. Eventuellt kan du skrive vsim work.sr_latch i kommandovinduet&lt;br /&gt;
&lt;br /&gt;
Questa bruker et standard X-basert vindusoppsett, og er derfor noen forskjellig fra de andre Mentor-programmene. Når du starter simulatoren åpnes det et vindu som vist i figur 1. Begynn med å åpne diverse vinduer:&lt;br /&gt;
&lt;br /&gt;
* View &amp;gt; Wave&lt;br /&gt;
&lt;br /&gt;
* View &amp;gt; Objects&lt;br /&gt;
&lt;br /&gt;
* View &amp;gt; Locals&lt;br /&gt;
&lt;br /&gt;
Man kan også gi kommandoer i Questa-vinduet. F.eks.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Wave *&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dra de signalene du vil se på i wave vinduet fra object vinduet.&lt;br /&gt;
&lt;br /&gt;
Signalverdier settes med kommandoen &#039;force&#039; eller med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Force &amp;gt; Force (i &amp;quot;Signals&amp;quot; vinduet)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dersom et av signalene skal være klokkesignal, kan dette gjøres enkelt med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Force &amp;gt; Clock (i &amp;quot;Signals&amp;quot; vinduet)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Eksempler==&lt;br /&gt;
===Signalflyt i en SR-lås===&lt;br /&gt;
&lt;br /&gt;
Simuler SR-låsen. Begynn med å påtrykke stimuli til alle signaler ved tid 0 (t0). Bruk STEP-knappen for å simulere på delta-tid-nivå. (Om en holder musepekeren over knappene i Questa, kommer det en forklarende tekst opp.) Når verdiene er stabile kjører du i f.eks. 100 ns før du endrer stimuli (skriv &#039;&#039;run 100&#039;&#039; i et av vinduene). Tilsvarende kan du endre stimuli ved å skrive f.eks. &#039;&#039;force S 0&#039;&#039; i hoved-vinduet. Legg merke til den røde pilen som peker på den linjen som blir utført.&lt;br /&gt;
&lt;br /&gt;
Hvis du vil begynne på ny kan du velge&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
File &amp;gt; Restart -f&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.ALL;&lt;br /&gt;
&lt;br /&gt;
ENTITY SR_latch IS&lt;br /&gt;
PORT (&lt;br /&gt;
S,R  : IN std_logic ;&lt;br /&gt;
Q,QB : INOUT std_logic );&lt;br /&gt;
END SR_latch;&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE behave OF SR_latch IS&lt;br /&gt;
&lt;br /&gt;
BEGIN  --  behave&lt;br /&gt;
Q &amp;lt;= S nand QB;&lt;br /&gt;
QB &amp;lt;= R nand Q;&lt;br /&gt;
END behave;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Signaler og variable===&lt;br /&gt;
&lt;br /&gt;
Simuler VHDL-koden under. Bruk Step eller Step Over for å følge prosedyrens utvikling linje for linje. Simulere med optimaliseringsopsjon &amp;quot;-voptargs=+acc&amp;quot; for å kunne se variablene i wave-vinduet:&lt;br /&gt;
&lt;br /&gt;
 vsim -voptargs=+acc sign_var&lt;br /&gt;
&lt;br /&gt;
Bruk View &amp;gt; Objects for å kikke på signalene og View &amp;gt; Local for å se innholdet i variablene. Forklar endringene i signaler og variable. Hva er forskjellen som funksjon av tid/delta-tid?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.ALL;&lt;br /&gt;
&lt;br /&gt;
ENTITY sign_var IS&lt;br /&gt;
  PORT (clk  : IN std_logic);&lt;br /&gt;
END sign_var;&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE difference OF sign_var IS&lt;br /&gt;
&lt;br /&gt;
signal SA: bit := &#039;0&#039;;&lt;br /&gt;
signal SB: bit := &#039;1&#039;;&lt;br /&gt;
&lt;br /&gt;
begin  --  difference&lt;br /&gt;
p_test: process&lt;br /&gt;
  variable A: bit := &#039;0&#039;;&lt;br /&gt;
  variable B: bit := &#039;1&#039;;&lt;br /&gt;
  begin&lt;br /&gt;
    wait until rising_edge(clk);&lt;br /&gt;
    A := B;&lt;br /&gt;
    B := A;&lt;br /&gt;
    SA &amp;lt;= SB after 5 ns;&lt;br /&gt;
    SB &amp;lt;= SA after 5 ns;&lt;br /&gt;
  end process p_test;&lt;br /&gt;
end architecture difference;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Bitvis_UVVM_VHDL_Verification_Component_Framework&amp;diff=2903</id>
		<title>Bitvis UVVM VHDL Verification Component Framework</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Bitvis_UVVM_VHDL_Verification_Component_Framework&amp;diff=2903"/>
		<updated>2024-02-13T12:14:01Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: /* Simulation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is heavily based on the Powerpoint-presentation found [http://bitvis.no/media/15298/Simple_TB_step_by_step.pps here].&amp;lt;ref&amp;gt;UVVM LICENSE AGREEMENT&lt;br /&gt;
IMPORTANT - READ BEFORE USING OR COPYING.&lt;br /&gt;
THIS IS THE MIT LICENSE, see https://opensource.org/licenses/MIT&lt;br /&gt;
------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Copyright (c) 2016 by Bitvis AS&lt;br /&gt;
&lt;br /&gt;
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated&lt;br /&gt;
documentation files (the &amp;quot;Software&amp;quot;), to deal in the Software without restriction, including without limitation&lt;br /&gt;
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, &lt;br /&gt;
and to permit persons to whom the Software is furnished to do so, subject to the following conditions:&lt;br /&gt;
&lt;br /&gt;
The above copyright notice and this permission notice shall be included in all copies or substantial portions of &lt;br /&gt;
the Software.&lt;br /&gt;
&lt;br /&gt;
THE SOFTWARE IS PROVIDED &amp;quot;AS IS&amp;quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE&lt;br /&gt;
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS&lt;br /&gt;
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR&lt;br /&gt;
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.&amp;lt;/ref&amp;gt;&lt;br /&gt;
The presentation can also be found in the uvvm_util folder.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Bitvis UVVM VVC Framework is a complete framework for making VHDL testbenches for &lt;br /&gt;
verification of FPGA and ASIC desing. You can download the complete code-base, examples and simulations scripts from the [https://github.com/UVVM/UVVM_All Bitvis github]. &lt;br /&gt;
&lt;br /&gt;
=== What&#039;s in the folders? ===&lt;br /&gt;
[[File:20160302215840!1.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
The download includes severals folders:&lt;br /&gt;
* bitvis_irqc - example VHDL design + testbench&lt;br /&gt;
* bitvis_uart - example VHDL design + testbench&lt;br /&gt;
* bitvis_vip_sbi - Verification IP(VIP) for simple bus interface(SBI)&lt;br /&gt;
* bitvis_vip_uart - VIP for UART TX and RX&lt;br /&gt;
* uvvm_util - UVVM utility library - sufficient for simple testbenches&lt;br /&gt;
* uvvm_vvc_framework - Framework for more advanced tutorials&lt;br /&gt;
&lt;br /&gt;
=== IRQC ===&lt;br /&gt;
[[File:irqc.png|thumb]]&lt;br /&gt;
The provided example VHDL design is a simple interrupt controller with several internal registers, a bus interface and some input and output signals.&lt;br /&gt;
&lt;br /&gt;
[[File:irqc2.png|350px]]&lt;br /&gt;
&lt;br /&gt;
== UVVM Utility Library - Testbench creation ==&lt;br /&gt;
Copy the folders bitvis_irqc, bitvis_vip_sbi and uvvm_util to another location before editing the files.&lt;br /&gt;
=== Generate TB entity with DUT instantiated ===&lt;br /&gt;
Our TB entity can in many cases be generated from several tools. Notepad++ (among other) supports plugins that enables copying an entity and pasting it as an instantiation, and also as a complete testbench template. However, we will change some of our signals so that they fit the VIP SBI BFM. The signals to and from the CPU will be converted to t_sbi_if record, which is a type that includes all the SBI signals (cs, addr, rd, wr, wdata, ready and rdata).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--Standard libraries&lt;br /&gt;
library IEEE;&lt;br /&gt;
use IEEE.std_logic_1164.all;&lt;br /&gt;
use IEEE.numeric_std.all;&lt;br /&gt;
&lt;br /&gt;
-- Library enabling control of the simulation from VHDL. Eg. std.env.stop&lt;br /&gt;
library STD;&lt;br /&gt;
use std.env.all;&lt;br /&gt;
&lt;br /&gt;
-- Obviously the UVVM library&lt;br /&gt;
library uvvm_util;&lt;br /&gt;
context uvvm_util.uvvm_util_context;&lt;br /&gt;
&lt;br /&gt;
-- We will use this library later when implementing the Bus Functional Model&lt;br /&gt;
-- Includes among much else the record type t_sbi_if and many functions&lt;br /&gt;
-- If other buses are used, you will have to change this library&lt;br /&gt;
library bitvis_vip_sbi;&lt;br /&gt;
use bitvis_vip_sbi.sbi_bfm_pkg.all;&lt;br /&gt;
&lt;br /&gt;
-- This file includes definitions of everything from registers to record types&lt;br /&gt;
use work.irqc_pif_pkg.all;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Test case entity&lt;br /&gt;
entity irqc_tb is&lt;br /&gt;
end entity;&lt;br /&gt;
&lt;br /&gt;
-- Test case architecture&lt;br /&gt;
architecture func of irqc_tb is&lt;br /&gt;
&lt;br /&gt;
  -- DSP interface and general control signals&lt;br /&gt;
  signal clk           : std_logic  := &#039;0&#039;;&lt;br /&gt;
  signal arst          : std_logic  := &#039;0&#039;;&lt;br /&gt;
  -- CPU interface&lt;br /&gt;
  -- t_sbi_if is from the verification IP SBI&lt;br /&gt;
  -- init_sbi_if_signals initialize the inputs to 0 and the outputs to Z&lt;br /&gt;
  signal sbi_if : t_sbi_if(addr(2 downto 0), wdata(7 downto 0), rdata(7 downto 0)) := init_sbi_if_signals(3, 8);&lt;br /&gt;
  &lt;br /&gt;
  -- Interrupt related signals&lt;br /&gt;
  signal irq_source    : std_logic_vector(C_NUM_SOURCES-1 downto 0) := (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
  signal irq2cpu       : std_logic := &#039;0&#039;;&lt;br /&gt;
  signal irq2cpu_ack   : std_logic := &#039;0&#039;;&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
  -----------------------------------------------------------------------------&lt;br /&gt;
  -- Instantiate DUT&lt;br /&gt;
  -----------------------------------------------------------------------------&lt;br /&gt;
  i_irqc: entity work.irqc&lt;br /&gt;
    port map (&lt;br /&gt;
    -- DSP interface and general control signals&lt;br /&gt;
        clk             =&amp;gt; clk,&lt;br /&gt;
        arst            =&amp;gt; arst,&lt;br /&gt;
    -- CPU interface&lt;br /&gt;
        cs              =&amp;gt; sbi_if.cs,             -- NOTICE THE SIGNALS ARE NOW SBI_IF&lt;br /&gt;
        addr            =&amp;gt; sbi_if.addr,&lt;br /&gt;
        wr              =&amp;gt; sbi_if.wena,&lt;br /&gt;
        rd              =&amp;gt; sbi_if.rena,&lt;br /&gt;
        din             =&amp;gt; sbi_if.wdata,&lt;br /&gt;
        dout            =&amp;gt; sbi_if.rdata,&lt;br /&gt;
    -- Interrupt related signals&lt;br /&gt;
        irq_source      =&amp;gt; irq_source,&lt;br /&gt;
        irq2cpu         =&amp;gt; irq2cpu,&lt;br /&gt;
        irq2cpu_ack     =&amp;gt; irq2cpu_ack&lt;br /&gt;
        );&lt;br /&gt;
 &lt;br /&gt;
end func;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support process for clock generation ===&lt;br /&gt;
We now have to add a support process that controls the clock. This has to allow enabling/disabling from the test sequencer. We add the following before &amp;quot;begin&amp;quot; in our architecture:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-- Added for clock generation&lt;br /&gt;
  signal clock_ena  : boolean := false;&lt;br /&gt;
&lt;br /&gt;
  constant C_CLK_PERIOD : time := 10 ns;&lt;br /&gt;
  &lt;br /&gt;
  procedure clock_gen(&lt;br /&gt;
    signal   clock_signal  : inout std_logic;&lt;br /&gt;
    signal   clock_ena     : in    boolean;&lt;br /&gt;
    constant clock_period  : in    time&lt;br /&gt;
  ) is&lt;br /&gt;
    variable v_first_half_clk_period : time := C_CLK_PERIOD / 2;&lt;br /&gt;
  begin&lt;br /&gt;
    loop&lt;br /&gt;
      if not clock_ena then&lt;br /&gt;
        wait until clock_ena;&lt;br /&gt;
      end if;&lt;br /&gt;
      wait for v_first_half_clk_period;&lt;br /&gt;
      clock_signal &amp;lt;= not clock_signal;&lt;br /&gt;
      wait for (clock_period - v_first_half_clk_period);&lt;br /&gt;
      clock_signal &amp;lt;= not clock_signal;&lt;br /&gt;
    end loop;&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our clock can now be activated from the test sequencer (this will be added in the next step):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-- After begin in the architecture&lt;br /&gt;
clock_gen(clk, clock_ena, C_CLK_PERIOD);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Inside the test sequencer process&lt;br /&gt;
clock_ena &amp;lt;= true;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add test sequencer process ===&lt;br /&gt;
The next step is to add the test sequencer process. This process controls everything from initialization to termination of the simulation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 -- Set upt clock generator&lt;br /&gt;
  clock_gen(clk, clock_ena, C_CLK_PERIOD);      &lt;br /&gt;
 &lt;br /&gt;
  ------------------------------------------------&lt;br /&gt;
  -- PROCESS: p_main&lt;br /&gt;
  ------------------------------------------------&lt;br /&gt;
  p_main : process&lt;br /&gt;
  -- The scope tells you where log messages originates - C_SCOPE tells us they originate from the default test sequencer scope&lt;br /&gt;
  constant C_SCOPE     : string  := C_TB_SCOPE_DEFAULT;&lt;br /&gt;
  -- This is where we will add some procedures later to simplify the tests&lt;br /&gt;
  &lt;br /&gt;
  begin&lt;br /&gt;
  &lt;br /&gt;
  --Print the configuration to the log&lt;br /&gt;
  report_global_ctrl(VOID);&lt;br /&gt;
  report_msg_id_panel(VOID);&lt;br /&gt;
  &lt;br /&gt;
  enable_log_msg(ALL_MESSAGES);&lt;br /&gt;
  --disable_log_msg&lt;br /&gt;
  --enable_log_msg(ID_LOG_HDR);&lt;br /&gt;
  &lt;br /&gt;
  log(ID_LOG_HDR, &amp;quot;Start Simulation of TB for IRQC&amp;quot;, C_SCOPE);&lt;br /&gt;
  ------------------------------------------------------------&lt;br /&gt;
  clock_ena &amp;lt;= true;   -- to start clock generator&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  ------------------------------------------------------------&lt;br /&gt;
  -- End the simulation&lt;br /&gt;
  wait for 1000 ns;                       -- to allow some time for completion&lt;br /&gt;
  report_alert_counters(FINAL);            -- Report final counters and print conclusion for simulation (Success/Fail)&lt;br /&gt;
  log(ID_LOG_HDR, &amp;quot;SIMULATION COMPLETED&amp;quot;, C_SCOPE);&lt;br /&gt;
  &lt;br /&gt;
  --Finish the simulation&lt;br /&gt;
  std.env.stop;&lt;br /&gt;
  wait; -- to stop completely&lt;br /&gt;
  end process p_main;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Simulation==&lt;br /&gt;
We now have the skeleton of the testbench, which we will develop further. But now, let&#039;s see if everything works. Bitvis have created simulation scripts for the IRQC example that compiles everything we need, from the source files of the VHDL design, to the testbench (if you called the file irqc_tb.vhd and placed it in the tb-folder) and the SBI BFM and the UVVM library. Open up QuestaSim/ModelSim.&lt;br /&gt;
Change directory to the script folder (where you have copied the UVVM files), for example in phys321/bitviswiki.....:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ~/phys321/bitviswiki/bitvis_irqc/script&lt;br /&gt;
do compile_and_sim_all.do&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will present our result in the transcript windows, but also write _Log.txt file which includes all the information we have asked for. We see that we get the results from the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
report_global_ctrl(VOID);&lt;br /&gt;
report_msg_id_panel(VOID);&lt;br /&gt;
enable_log_msg(ALL_MESSAGES);&lt;br /&gt;
log(ID_LOG_HDR, &amp;quot;Start Simulation of TB for IRQC&amp;quot;, C_SCOPE);&lt;br /&gt;
report_alert_counters(FINAL);&lt;br /&gt;
log(ID_LOG_HDR, &amp;quot;SIMULATION COMPLETED&amp;quot;, C_SCOPE);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Commenting these out will result in an empty log.&lt;br /&gt;
&lt;br /&gt;
== Verbosity control ==&lt;br /&gt;
We want to able to control the amount of information in our logs, and the framework enables us to prioritize messages based on ID. This makes it easy to turn on or off the information we want.&lt;br /&gt;
To turn on a specific ID&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
enable_log_msg(IDNAME);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Turn off:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disable_log_msg(IDNAME);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For writing a message to a certain log ID:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
log(IDNAME, &amp;quot;MESSAGE HERE&amp;quot;, C_SCOPE);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Remember that C_SCOPE just tells us that the message originated from the default scope and will look like &amp;quot;TB seq.&amp;quot; in the log file.&lt;br /&gt;
&lt;br /&gt;
Exampled IDs:&lt;br /&gt;
* ID_LOG_HDR,           -- ONLY allowed in test sequencer, Log section headers&lt;br /&gt;
* ID_SEQUENCER,         -- ONLY allowed in test sequencer, Normal log (not log headers)&lt;br /&gt;
* ID_BFM,               -- Used inside a BFM (to log BFM access)&lt;br /&gt;
* ID_CLOCK_GEN,         -- Used for logging when clock generators are enabled or disabled&lt;br /&gt;
* ALL_MESSAGES          -- Applies to ALL message ID apart from ID_NEVER&lt;br /&gt;
&lt;br /&gt;
You&#039;ll find all the different ID&#039;s in the UVVM Utility Library Quick Reference or defined in uvvm_util/adaptions_pkg.vhd. This also where C_TB_SCOPE_DEFAULT is defined.&lt;br /&gt;
&lt;br /&gt;
== Implement first tests ==&lt;br /&gt;
[[File:tb.png|thumb|upright=0.35]]&lt;br /&gt;
We want to check and verify that our testbench is up and running and to verify our first tests of the DUT. This means that we have to able to set all our signals passive, apply a reset signal and then check the default outputs of the DUT.&lt;br /&gt;
&lt;br /&gt;
Instead of setting all our signals passive one-by-one in our test sequencer we declare a procedure in our p_main process(this is done before begin):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
procedure set_inputs_passive(&lt;br /&gt;
      dummy   : t_void) is           --dummy variable is included only to allow calling the procedure with parenthesis for readability&lt;br /&gt;
    begin&lt;br /&gt;
      sbi_if.cs           &amp;lt;= &#039;0&#039;;&lt;br /&gt;
      sbi_if.addr         &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
      sbi_if.wena         &amp;lt;= &#039;0&#039;;&lt;br /&gt;
      sbi_if.rena         &amp;lt;= &#039;0&#039;;&lt;br /&gt;
      sbi_if.wdata          &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
      irq_source   &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
      irq2cpu_ack  &amp;lt;= &#039;0&#039;;&lt;br /&gt;
      log(ID_SEQUENCER_SUB, &amp;quot;All inputs set passive&amp;quot;, C_SCOPE);&lt;br /&gt;
    end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the procedure declaration also includes a dummy variable parameter. This means that we will be able to call the procedure with the more readable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set_inputs_passive(VOID);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rather than:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set_inputs_passive;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
which is more ambigious.&lt;br /&gt;
&lt;br /&gt;
We may also would like to send pulses on different signals, f.ex. sending a pulse on our reset to see if it behaves like intended. We therefore can include a pulse procedure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
procedure pulse(&lt;br /&gt;
      signal   target        : inout  std_logic_vector;&lt;br /&gt;
      constant pulse_value   : in     std_logic_vector;&lt;br /&gt;
      signal   clock_signal  : in     std_logic;&lt;br /&gt;
      constant num_periods   : in     natural;&lt;br /&gt;
      constant msg           : in     string) is&lt;br /&gt;
    begin&lt;br /&gt;
      if num_periods &amp;gt; 0 then&lt;br /&gt;
        wait until falling_edge(clock_signal);&lt;br /&gt;
        target &amp;lt;= pulse_value;&lt;br /&gt;
        for i in 1 to num_periods loop&lt;br /&gt;
          wait until falling_edge(clock_signal);&lt;br /&gt;
        end loop;&lt;br /&gt;
      else&lt;br /&gt;
        target &amp;lt;= pulse_value;&lt;br /&gt;
        wait for 0 ns;  -- Delta cycle only&lt;br /&gt;
      end if;&lt;br /&gt;
      target(target&#039;range) &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
      log(ID_SEQUENCER_SUB, &amp;quot;Pulsed to &amp;quot; &amp;amp; to_string(pulse_value, HEX, AS_IS, INCL_RADIX) &amp;amp; &amp;quot;. &amp;quot; &amp;amp; msg, C_SCOPE);&lt;br /&gt;
    end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example the test sequencer is required to inform the procedure of what value the pulse is to take. The call to the procedure would take the following form:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
pulse(arst, &#039;Z&#039;, clk, 10, &amp;quot;Log message - Im pulsing the value &#039;Z&#039;&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
But a more specific overload can be created where pulse always takes value &#039;1&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
procedure pulse(&lt;br /&gt;
      signal   target          : inout std_logic;&lt;br /&gt;
      signal   clock_signal    : in    std_logic;&lt;br /&gt;
      constant num_periods     : in    natural;&lt;br /&gt;
      constant msg             : in    string&lt;br /&gt;
    ) is&lt;br /&gt;
    begin&lt;br /&gt;
      if num_periods &amp;gt; 0 then&lt;br /&gt;
        wait until falling_edge(clock_signal);&lt;br /&gt;
        target  &amp;lt;= &#039;1&#039;;&lt;br /&gt;
        for i in 1 to num_periods loop&lt;br /&gt;
          wait until falling_edge(clock_signal);&lt;br /&gt;
        end loop;&lt;br /&gt;
      else&lt;br /&gt;
        target  &amp;lt;= &#039;1&#039;;&lt;br /&gt;
        wait for 0 ns;  -- Delta cycle only&lt;br /&gt;
      end if;&lt;br /&gt;
      target  &amp;lt;= &#039;0&#039;;&lt;br /&gt;
      log(ID_SEQUENCER_SUB, msg, C_SCOPE);&lt;br /&gt;
    end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These procedures can now be called directly from our test sequence:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set_inputs_passive(VOID);&lt;br /&gt;
pulse(arst, clk, 10, &amp;quot;pulsed reset-signal - active for 10T&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To check signal values we can use the built-in check function check_value():&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
check_value(irq2cpu, &#039;X&#039;, ERROR, &amp;quot;Interrupt to CPU must be default inactive&amp;quot;, C_SCOPE);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above call checks if the signal irq2cpu is &#039;X&#039;, and obviously fail if everything works correctly and gives the following message:&lt;br /&gt;
&lt;br /&gt;
[[File:error.png|700px]]&lt;br /&gt;
&lt;br /&gt;
If we want we can change the number of errors logged before the simulation stops:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set_alert_stop_limit(ERROR, 3);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We now have all the tools needed for the first tests in our sequencer:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set_inputs_passive(VOID);&lt;br /&gt;
pulse(arst, clk, 10, &amp;quot;Pulsed reset-signal - active for 10T&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
check_value(C_NUM_SOURCES &amp;gt; 0, FAILURE, &amp;quot;Must be at least 1 interrupt source&amp;quot;, C_SCOPE);&lt;br /&gt;
check_value(C_NUM_SOURCES &amp;lt;= 8, TB_WARNING, &amp;quot;This TB is only checking IRQC with up to 8 interrupt sources&amp;quot;, C_SCOPE);&lt;br /&gt;
  &lt;br /&gt;
log(ID_LOG_HDR, &amp;quot;Check defaults on output ports&amp;quot;, C_SCOPE);&lt;br /&gt;
------------------------------------------------------------&lt;br /&gt;
check_value(irq2cpu, &#039;0&#039;, ERROR, &amp;quot;Interrupt to CPU must be default inactive&amp;quot;, C_SCOPE);&lt;br /&gt;
check_value(sbi_if.rdata, x&amp;quot;00&amp;quot;, ERROR, &amp;quot;Register data bus output must be default passive&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will give us the following log:&lt;br /&gt;
&lt;br /&gt;
[[File:sim.png|800px]]&lt;br /&gt;
&lt;br /&gt;
This information may only interesting initially and for debug, and can be turned on or off by use of ID.&lt;br /&gt;
&lt;br /&gt;
== Subprograms ==&lt;br /&gt;
Some of our testbench code will be repeated several times and the testbench may therefore benefit from creating several subprograms. Obvious examples for our IRQC is:&lt;br /&gt;
- Register access&lt;br /&gt;
- Signal checkers&lt;br /&gt;
- Interrupt source pulsing?&lt;br /&gt;
- Interrupt acknowledge pulsing?&lt;br /&gt;
- (Report/log method)&lt;br /&gt;
- (Alert-handling)&lt;br /&gt;
- (reset, set_passive, ...)&lt;br /&gt;
&lt;br /&gt;
We&#039;ve already created and declared set_passive and pulse procedures, but we could f.ex create overloads for UVVM procedures:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    -- Log overloads for simplification&lt;br /&gt;
    procedure log(&lt;br /&gt;
      msg   : string) is&lt;br /&gt;
    begin&lt;br /&gt;
      log(ID_SEQUENCER, msg, C_SCOPE);&lt;br /&gt;
    end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This exact function is already overloaded in the UVVM packages, so including this in our testbench would produce compilation errors. So, let&#039;s not include it, but view it as an example of how it&#039;s done.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s say that it is probable that we&#039;ll want to change the number of interrupt sources that the controller can handle. We will then want to able to easily change vectors to the appropriate size. One way is to declare procedures that can trim and fit vectors. This way we can simply change a constant to change the number of sources.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  subtype t_irq_source is std_logic_vector(C_NUM_SOURCES-1 downto 0);&lt;br /&gt;
&lt;br /&gt;
  -- Trim (cut) a given vector to fit the number of irq sources (i.e. pot. reduce width)&lt;br /&gt;
  function trim(&lt;br /&gt;
    constant source   : std_logic_vector;&lt;br /&gt;
    constant num_bits : positive := C_NUM_SOURCES)&lt;br /&gt;
  return t_irq_source is&lt;br /&gt;
    variable v_result : std_logic_vector(source&#039;length-1 downto 0) := source;&lt;br /&gt;
  begin&lt;br /&gt;
    return v_result(num_bits-1 downto 0);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  -- Fit a given vector to the number of irq sources by masking with zeros above irq width&lt;br /&gt;
  function fit(&lt;br /&gt;
    constant source   : std_logic_vector;&lt;br /&gt;
    constant num_bits : positive := C_NUM_SOURCES)&lt;br /&gt;
  return std_logic_vector is&lt;br /&gt;
    variable v_result : std_logic_vector(source&#039;length-1 downto 0) := (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
    variable v_source : std_logic_vector(source&#039;length-1 downto 0) := source;&lt;br /&gt;
  begin&lt;br /&gt;
    v_result(num_bits-1 downto 0) := v_source(num_bits-1 downto 0);&lt;br /&gt;
    return v_result;&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All IRQC-dedicated subprograms should be declared locally, but more common (f.ex bus-specific) should be declared in common package that can be shared with other.&lt;br /&gt;
&lt;br /&gt;
== Register access ==&lt;br /&gt;
To access the IRQC&#039;s registers we need to go through the actual process of writing and reading data from them. Fortunately, Bitvis have already taken the responsibility of writing the BFM for the SBI. This doesn&#039;t mean that we doesn&#039;t have to understand what&#039;s going on, since we&#039;ll have to write our own BFM&#039;s for other buses that we use(Avalon, AXI, etc). &#039;&#039;&#039;January 2017 Bitvis announced that they released VVC for Avalon-MM and AXI4-lite.&#039;&#039;&#039; So we should investigate the BFM procedures. We want to check register values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
procedure sbi_check (&lt;br /&gt;
    constant addr_value   : in    unsigned;&lt;br /&gt;
    constant data_exp     : in    std_logic_vector;&lt;br /&gt;
    constant msg          : in    string;&lt;br /&gt;
    signal   clk          : in    std_logic;&lt;br /&gt;
    signal   cs           : inout std_logic;&lt;br /&gt;
    signal   addr         : inout unsigned;&lt;br /&gt;
    signal   rd           : inout std_logic;&lt;br /&gt;
    signal   wr           : inout std_logic;&lt;br /&gt;
    signal   ready        : in    std_logic;&lt;br /&gt;
    signal   rdata        : in    std_logic_vector;&lt;br /&gt;
    constant alert_level  : in    t_alert_level     := error;&lt;br /&gt;
    constant scope        : in    string            := C_SCOPE;&lt;br /&gt;
    constant msg_id_panel : in    t_msg_id_panel    := shared_msg_id_panel;&lt;br /&gt;
    constant config       : in    t_sbi_bfm_config  := C_SBI_BFM_CONFIG_DEFAULT&lt;br /&gt;
  ) is&lt;br /&gt;
    constant proc_name    : string :=  &amp;quot;sbi_check&amp;quot;;&lt;br /&gt;
    constant proc_call    : string :=  &amp;quot;sbi_check(A:&amp;quot; &amp;amp; to_string(addr_value, HEX, AS_IS, INCL_RADIX) &amp;amp;&lt;br /&gt;
                                       &amp;quot;, &amp;quot;  &amp;amp; to_string(data_exp, HEX, AS_IS, INCL_RADIX) &amp;amp; &amp;quot;)&amp;quot;;&lt;br /&gt;
    -- Normalize to the DUT addr/data widths&lt;br /&gt;
    variable v_normalised_addr    : unsigned(addr&#039;length-1 downto 0) :=&lt;br /&gt;
      normalize_and_check(addr_value, addr, ALLOW_WIDER_NARROWER, &amp;quot;addr_value&amp;quot;, &amp;quot;sbi_core_in.addr&amp;quot;, msg);&lt;br /&gt;
    -- Helper variables&lt;br /&gt;
    variable v_data_value         : std_logic_vector(rdata&#039;length - 1 downto 0);&lt;br /&gt;
    variable v_check_ok           : boolean;&lt;br /&gt;
    variable v_clk_cycles_waited  : natural := 0;&lt;br /&gt;
  begin&lt;br /&gt;
    sbi_read(addr_value, v_data_value, msg, clk, cs, addr, rd, wr, ready, rdata, scope, msg_id_panel, config, proc_name);&lt;br /&gt;
&lt;br /&gt;
    -- Compare values, but ignore any leading zero&#039;s if widths are different.&lt;br /&gt;
    -- Use ID_NEVER so that check_value method does not log when check is OK,&lt;br /&gt;
    -- log it here instead.&lt;br /&gt;
    v_check_ok := check_value(v_data_value, data_exp, alert_level, msg, scope, HEX_BIN_IF_INVALID, SKIP_LEADING_0, ID_NEVER, msg_id_panel, proc_call);&lt;br /&gt;
    if v_check_ok then&lt;br /&gt;
      log(config.id_for_bfm, proc_call &amp;amp; &amp;quot;=&amp;gt; OK, read data = &amp;quot; &amp;amp; to_string(v_data_value, HEX, SKIP_LEADING_0, INCL_RADIX) &amp;amp; &amp;quot;. &amp;quot; &amp;amp; msg, scope, msg_id_panel);&lt;br /&gt;
    end if;&lt;br /&gt;
  end procedure;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We see that sbi_check() calls sbi_read() before it checks if the read value is the expected value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
procedure sbi_read (&lt;br /&gt;
    constant addr_value    : in     unsigned;&lt;br /&gt;
    variable data_value    : out    std_logic_vector;&lt;br /&gt;
    constant msg           : in     string;&lt;br /&gt;
    signal   clk           : in     std_logic;&lt;br /&gt;
    signal   cs            : inout  std_logic;&lt;br /&gt;
    signal   addr          : inout  unsigned;&lt;br /&gt;
    signal   rd            : inout  std_logic;&lt;br /&gt;
    signal   wr            : inout  std_logic;&lt;br /&gt;
    signal   ready         : in     std_logic;&lt;br /&gt;
    signal   rdata         : in     std_logic_vector;&lt;br /&gt;
    constant scope         : in     string            := C_SCOPE;&lt;br /&gt;
    constant msg_id_panel  : in     t_msg_id_panel    := shared_msg_id_panel;&lt;br /&gt;
    constant config        : in     t_sbi_bfm_config  := C_SBI_BFM_CONFIG_DEFAULT;&lt;br /&gt;
    constant proc_name     : in     string            := &amp;quot;sbi_read&amp;quot;  -- overwrite if called from other procedure like sbi_check&lt;br /&gt;
  ) is&lt;br /&gt;
    constant proc_call            : string := &amp;quot;sbi_read(A:&amp;quot; &amp;amp; to_string(addr_value, HEX, AS_IS, INCL_RADIX) &amp;amp; &amp;quot;)&amp;quot;;&lt;br /&gt;
    -- Normalize to the DUT addr/data widths&lt;br /&gt;
    variable v_normalised_addr    : unsigned(addr&#039;length-1 downto 0) :=&lt;br /&gt;
        normalize_and_check(addr_value, addr, ALLOW_WIDER_NARROWER, &amp;quot;addr_value&amp;quot;, &amp;quot;sbi_core_in.addr&amp;quot;, msg);&lt;br /&gt;
    variable v_data_value         : std_logic_vector(data_value&#039;range);&lt;br /&gt;
    variable v_clk_cycles_waited  : natural := 0;&lt;br /&gt;
  begin&lt;br /&gt;
    wait_until_given_time_after_rising_edge(clk, config.clock_period/4);&lt;br /&gt;
    cs   &amp;lt;= &#039;1&#039;;&lt;br /&gt;
    wr   &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    rd   &amp;lt;= &#039;1&#039;;&lt;br /&gt;
    addr &amp;lt;= v_normalised_addr;&lt;br /&gt;
    wait for config.clock_period;&lt;br /&gt;
    while (config.use_ready_signal and ready = &#039;0&#039;) loop&lt;br /&gt;
      if v_clk_cycles_waited = 0 then&lt;br /&gt;
        log(config.id_for_bfm_wait, proc_call &amp;amp; &amp;quot; waiting for response (sbi ready=0)&amp;quot; &amp;amp; msg, scope, msg_id_panel);&lt;br /&gt;
      end if;&lt;br /&gt;
      wait for config.clock_period;&lt;br /&gt;
      v_clk_cycles_waited := v_clk_cycles_waited + 1;&lt;br /&gt;
      check_value(v_clk_cycles_waited &amp;lt;= config.max_wait_cycles, config.max_wait_cycles_severity,&lt;br /&gt;
                  &amp;quot;: Timeout while waiting for sbi ready&amp;quot;, scope, ID_NEVER, msg_id_panel, proc_call);&lt;br /&gt;
    end loop;&lt;br /&gt;
&lt;br /&gt;
    cs  &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    rd  &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    v_data_value  := rdata;&lt;br /&gt;
    data_value    := v_data_value;&lt;br /&gt;
    if proc_name = &amp;quot;sbi_read&amp;quot; then&lt;br /&gt;
      log(config.id_for_bfm, proc_call &amp;amp; &amp;quot;=&amp;gt; &amp;quot; &amp;amp; to_string(v_data_value, HEX, SKIP_LEADING_0, INCL_RADIX) &amp;amp; &amp;quot;. &amp;quot; &amp;amp; msg, scope, msg_id_panel);&lt;br /&gt;
    else&lt;br /&gt;
      -- Log will be handled by calling procedure (e.g. sbi_check)&lt;br /&gt;
    end if;&lt;br /&gt;
  end procedure;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We don&#039;t want to (and probably shouldnt) call the sbi_check and providing all the parameters each time. Some of this can be solved by the overloads with more standard parameters, and with our own check procedures declared locally in our testbench:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    procedure check(&lt;br /&gt;
      constant addr_value   : in natural;&lt;br /&gt;
      constant data_exp     : in std_logic_vector;&lt;br /&gt;
      constant alert_level  : in t_alert_level;&lt;br /&gt;
      constant msg          : in string) is&lt;br /&gt;
    begin&lt;br /&gt;
      sbi_check(to_unsigned(addr_value, sbi_if.addr&#039;length), data_exp, msg,&lt;br /&gt;
            clk, sbi_if, alert_level, C_SCOPE);&lt;br /&gt;
    end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The write procedure is also very handy and should be understood:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  procedure sbi_write (&lt;br /&gt;
    constant addr_value   : in    unsigned;&lt;br /&gt;
    constant data_value   : in    std_logic_vector;&lt;br /&gt;
    constant msg          : in    string;&lt;br /&gt;
    signal   clk          : in    std_logic;&lt;br /&gt;
    signal   cs           : inout std_logic;&lt;br /&gt;
    signal   addr         : inout unsigned;&lt;br /&gt;
    signal   rd           : inout std_logic;&lt;br /&gt;
    signal   wr           : inout std_logic;&lt;br /&gt;
    signal   ready        : in    std_logic;&lt;br /&gt;
    signal   wdata        : inout std_logic_vector;&lt;br /&gt;
    constant scope        : in    string            := C_SCOPE;&lt;br /&gt;
    constant msg_id_panel : in    t_msg_id_panel    := shared_msg_id_panel;&lt;br /&gt;
    constant config       : in    t_sbi_bfm_config  := C_SBI_BFM_CONFIG_DEFAULT&lt;br /&gt;
  ) is&lt;br /&gt;
    constant proc_name  : string :=  &amp;quot;sbi_write&amp;quot;;&lt;br /&gt;
    constant proc_call  : string :=  &amp;quot;sbi_write(A:&amp;quot; &amp;amp; to_string(addr_value, HEX, AS_IS, INCL_RADIX) &amp;amp;&lt;br /&gt;
                                     &amp;quot;, &amp;quot; &amp;amp; to_string(data_value, HEX, AS_IS, INCL_RADIX) &amp;amp; &amp;quot;)&amp;quot;;&lt;br /&gt;
    -- Normalise to the DUT addr/data widths&lt;br /&gt;
    variable v_normalised_addr    : unsigned(addr&#039;length-1 downto 0) :=&lt;br /&gt;
        normalize_and_check(addr_value, addr, ALLOW_WIDER_NARROWER, &amp;quot;addr_value&amp;quot;, &amp;quot;sbi_core_in.addr&amp;quot;, msg);&lt;br /&gt;
    variable v_normalised_data    : std_logic_vector(wdata&#039;length-1 downto 0) :=&lt;br /&gt;
        normalize_and_check(data_value, wdata, ALLOW_NARROWER, &amp;quot;data_value&amp;quot;, &amp;quot;sbi_core_in.wdata&amp;quot;, msg);&lt;br /&gt;
    variable v_clk_cycles_waited  : natural := 0;&lt;br /&gt;
  begin&lt;br /&gt;
    wait_until_given_time_after_rising_edge(clk, config.clock_period/4);&lt;br /&gt;
    cs    &amp;lt;= &#039;1&#039;;&lt;br /&gt;
    wr    &amp;lt;= &#039;1&#039;;&lt;br /&gt;
    rd    &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    addr  &amp;lt;= v_normalised_addr;&lt;br /&gt;
    wdata &amp;lt;= v_normalised_data;&lt;br /&gt;
&lt;br /&gt;
    wait for config.clock_period;&lt;br /&gt;
    while (config.use_ready_signal and ready = &#039;0&#039;) loop&lt;br /&gt;
      if v_clk_cycles_waited = 0 then&lt;br /&gt;
        log(config.id_for_bfm_wait, proc_call &amp;amp; &amp;quot; waiting for response (sbi ready=0)&amp;quot; &amp;amp; msg, scope, msg_id_panel);&lt;br /&gt;
      end if;&lt;br /&gt;
      wait for config.clock_period;&lt;br /&gt;
      v_clk_cycles_waited := v_clk_cycles_waited + 1;&lt;br /&gt;
      check_value(v_clk_cycles_waited &amp;lt;= config.max_wait_cycles, config.max_wait_cycles_severity,&lt;br /&gt;
                  &amp;quot;: Timeout while waiting for sbi ready&amp;quot;, scope, ID_NEVER, msg_id_panel, proc_call);&lt;br /&gt;
    end loop;&lt;br /&gt;
&lt;br /&gt;
    cs  &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    wr  &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    log(config.id_for_bfm, proc_call &amp;amp; &amp;quot; completed. &amp;quot; &amp;amp; msg, scope, msg_id_panel);&lt;br /&gt;
  end procedure;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We will create a local overload of this too:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
procedure write(&lt;br /&gt;
      constant addr_value   : in natural;&lt;br /&gt;
      constant data_value   : in std_logic_vector;&lt;br /&gt;
      constant msg          : in string) is&lt;br /&gt;
    begin&lt;br /&gt;
      sbi_write(to_unsigned(addr_value, sbi_if.addr&#039;length), data_value, msg,&lt;br /&gt;
            clk, sbi_if, C_SCOPE);&lt;br /&gt;
    end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We also need to set the sbi_if.ready signal high for this to work:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clock_generator(clk, clock_ena, C_CLK_PERIOD, &amp;quot;IRQC TB clock&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
-- Insert this here by the clock generator&lt;br /&gt;
sbi_if.ready &amp;lt;= &#039;1&#039;; -- always ready in the same clock cycle.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All this enables us to handle transactions at a high level. See Bitvis documentation for how to write your own BFM and what it should include(sanity checks, etc).&lt;br /&gt;
&lt;br /&gt;
[[File:bfm.png|550px]]&lt;br /&gt;
&lt;br /&gt;
== Checking register write and read ==&lt;br /&gt;
Now we&#039;re enabled to write to and read from the registers. The register addresses are defined in the IRQC package file irqc_pif_bkg.vhd. Notice that we also use the previously declared overloaded version of log() and fit().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
log(ID_LOG_HDR, &amp;quot;Check register defaults and access (write + read)&amp;quot;, C_SCOPE);&lt;br /&gt;
    ------------------------------------------------------------&lt;br /&gt;
    log(&amp;quot;\nChecking Register defaults&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, x&amp;quot;00&amp;quot;, ERROR, &amp;quot;IRR default&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IER, x&amp;quot;00&amp;quot;, ERROR, &amp;quot;IER default&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IPR, x&amp;quot;00&amp;quot;, ERROR, &amp;quot;IPR default&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRQ2CPU_ALLOWED, x&amp;quot;00&amp;quot;, ERROR, &amp;quot;IRQ2CPU_ALLOWED default&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    log(&amp;quot;\nChecking Register Write/Read&amp;quot;);&lt;br /&gt;
    write(C_ADDR_IER, fit(x&amp;quot;55&amp;quot;), &amp;quot;IER&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IER, fit(x&amp;quot;55&amp;quot;), ERROR, &amp;quot;IER pure readback&amp;quot;);&lt;br /&gt;
    write(C_ADDR_IER, fit(x&amp;quot;AA&amp;quot;), &amp;quot;IER&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IER, fit(x&amp;quot;AA&amp;quot;), ERROR, &amp;quot;IER pure readback&amp;quot;);&lt;br /&gt;
    write(C_ADDR_IER, fit(x&amp;quot;00&amp;quot;), &amp;quot;IER&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IER, fit(x&amp;quot;00&amp;quot;), ERROR, &amp;quot;IER pure readback&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This check will give us a nice log if everything turns out ok:&lt;br /&gt;
&lt;br /&gt;
[[File:sim2.png|700px]]&lt;br /&gt;
&lt;br /&gt;
However, if there&#039;s an error:&lt;br /&gt;
&lt;br /&gt;
[[File:error2.png|700px]]&lt;br /&gt;
&lt;br /&gt;
== Further tests ==&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve tested register read/write, we should test the trigger/clear mechanism. No further adding of procedures are necessary.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    log(ID_LOG_HDR, &amp;quot;Check register trigger/clear mechanism&amp;quot;, C_SCOPE);&lt;br /&gt;
    ------------------------------------------------------------&lt;br /&gt;
    write(C_ADDR_ITR, fit(x&amp;quot;AA&amp;quot;), &amp;quot;ITR : Set interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;AA&amp;quot;), ERROR, &amp;quot;IRR&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ITR, fit(x&amp;quot;55&amp;quot;), &amp;quot;ITR : Set more interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;FF&amp;quot;), ERROR, &amp;quot;IRR&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ICR, fit(x&amp;quot;71&amp;quot;), &amp;quot;ICR : Clear interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;8E&amp;quot;), ERROR, &amp;quot;IRR&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ICR, fit(x&amp;quot;85&amp;quot;), &amp;quot;ICR : Clear interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;0A&amp;quot;), ERROR, &amp;quot;IRR&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ITR, fit(x&amp;quot;55&amp;quot;), &amp;quot;ITR : Set more interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;5F&amp;quot;), ERROR, &amp;quot;IRR&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ICR, fit(x&amp;quot;5F&amp;quot;), &amp;quot;ICR : Clear interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;00&amp;quot;), ERROR, &amp;quot;IRR&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The UVVM Utility Library provides all necessary functions and procedures to do further tests. F.ex. we should send pulses on the irq_source signal to check if the design behaves correctly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
log(ID_LOG_HDR, &amp;quot;Check interrupt sources, IER, IPR and irq2cpu&amp;quot;, C_SCOPE);&lt;br /&gt;
    ------------------------------------------------------------&lt;br /&gt;
    log(&amp;quot;\nChecking interrupts and IRR&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ICR, fit(x&amp;quot;FF&amp;quot;), &amp;quot;ICR : Clear all interrupts&amp;quot;);&lt;br /&gt;
    pulse(irq_source, trim(x&amp;quot;AA&amp;quot;), clk, 1, &amp;quot;Pulse irq_source 1T&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;AA&amp;quot;), ERROR, &amp;quot;IRR after irq pulses&amp;quot;);&lt;br /&gt;
    pulse(irq_source, trim(x&amp;quot;01&amp;quot;), clk, 1, &amp;quot;Add more interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;AB&amp;quot;), ERROR, &amp;quot;IRR after irq pulses&amp;quot;);&lt;br /&gt;
    pulse(irq_source, trim(x&amp;quot;A1&amp;quot;), clk, 1, &amp;quot;Repeat same interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;AB&amp;quot;), ERROR, &amp;quot;IRR after irq pulses&amp;quot;);&lt;br /&gt;
    pulse(irq_source, trim(x&amp;quot;54&amp;quot;), clk, 1, &amp;quot;Add remaining interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;FF&amp;quot;), ERROR, &amp;quot;IRR after irq pulses&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ICR, fit(x&amp;quot;AA&amp;quot;), &amp;quot;ICR : Clear half the interrupts&amp;quot;);&lt;br /&gt;
    pulse(irq_source, trim(x&amp;quot;A0&amp;quot;), clk, 1, &amp;quot;Add more interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;F5&amp;quot;), ERROR, &amp;quot;IRR after irq pulses&amp;quot;);&lt;br /&gt;
    write(C_ADDR_ICR, fit(x&amp;quot;FF&amp;quot;), &amp;quot;ICR : Clear all interrupts&amp;quot;);&lt;br /&gt;
    check(C_ADDR_IRR, fit(x&amp;quot;00&amp;quot;), ERROR, &amp;quot;IRR after clearing all&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Check stable ===&lt;br /&gt;
Another test provided by UVVM is check_stable(). This function enables us to test if a signal is holding the same value for a minimum provided time. We must declare a variable that holds the time from which we want to test if the signal is stable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v_time_stamp := now;  -- time from which irq2cpu should be stable off until triggered&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Later we&#039;re now able to test if the signal has been holding the same value the whole period:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
check_stable(irq2cpu, (now - v_time_stamp), ERROR, &amp;quot;No spikes allowed on irq2cpu&amp;quot;, C_SCOPE);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remember to declare the variable in the process:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
variable v_time_stamp   : time := 0 ns;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Await value ===&lt;br /&gt;
To check if a signal gets the expected value within a specified time value we use await_vale(). The test below throws an error if irq2cpu doesn&#039;t obtain the value &#039;1&#039; within 0 ns(!). Therefore expected immediately:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
await_value(irq2cpu, &#039;1&#039;, 0 ns, C_CLK_PERIOD, ERROR, &amp;quot;Interrupt expected immediately&amp;quot;, C_SCOPE);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other useful functions ===&lt;br /&gt;
&lt;br /&gt;
Check the UVVM Utility Library Quick Reference for syntax details.&lt;br /&gt;
&lt;br /&gt;
==== await_change() ====&lt;br /&gt;
Expects and waits for a change on the given signal, inside a given time window. &lt;br /&gt;
&lt;br /&gt;
==== check_value_in_range() ====&lt;br /&gt;
Throws an error of the signal value is outside the specified minimum and maximum values.&lt;br /&gt;
&lt;br /&gt;
== UVVM VVC ==&lt;br /&gt;
Guide coming....&lt;br /&gt;
&lt;br /&gt;
== UVVM LICENCE AGREEMENT ==&lt;br /&gt;
{{reflist}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2902</id>
		<title>Synthese av VHDL</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2902"/>
		<updated>2024-01-24T07:58:50Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: /* Precision */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Syntetiseringen av VHDL kode===&lt;br /&gt;
&lt;br /&gt;
Grunnen til at vi skal syntetisere koden, er at vi må lage beskrivelse av koden tilpassa ein krets.&lt;br /&gt;
&lt;br /&gt;
Vi vil no prøve å synthesisere vhdl kode. Og etterpå vil vi lage ein testbenk der vi samanliknar utsignala frå den syntetiserte og den opprinnelige koden. Vi bruker ein alu som eksempel.&lt;br /&gt;
&lt;br /&gt;
==Precision==&lt;br /&gt;
&lt;br /&gt;
Precision bruker Vivado til å syntetisere vhdl-koden. For å starte synteseprogrammet:&lt;br /&gt;
&lt;br /&gt;
 export LM_LICENSE_FILE=1717@lisensserver:2100@lisensserver&lt;br /&gt;
 source /eda/Siemens/2023-24/scripts/PRECISION_2023.2_RHELx86.sh&lt;br /&gt;
 precision&lt;br /&gt;
&lt;br /&gt;
Erstatt lisensserver med rett navn på lisensserver.Nye versjoner av programvaren ligger i /eda/Siemens sortert på årstall.&lt;br /&gt;
&lt;br /&gt;
Velg deretter New Project, og deretter Add input file (i dette tilfelle add_sub_alu.vhd).&lt;br /&gt;
Så går vi inn på Setup design, velger ein kretsprodusent, den ønska kretsen og designfrekvens, for eksempel Zynq med frekvens 200MHz. For å få ut en vhdl fil av den syntetiserte koden må en gå på Tools-&amp;gt;Options-&amp;gt;Output og hak av for VHDL og trykk ok.&lt;br /&gt;
&lt;br /&gt;
Pass på at Precision finner Vivado, settes i menyen:&lt;br /&gt;
 Tools &amp;gt; Options &amp;gt; Place and Route Settings&lt;br /&gt;
deretter&lt;br /&gt;
 Vivado &amp;gt; Integrated Place and Route &amp;gt; path to Xilinx Vivado installation tree&lt;br /&gt;
settes til&lt;br /&gt;
 /eda/xilinx/Vivado/2020.2&lt;br /&gt;
&lt;br /&gt;
Trykk så compile, og synthesize. &lt;br /&gt;
No kan vi sjå på den generte kretsen i RTL Schematic og Technology Schematic (syntese med den valgte kretsen) under Schematics på venstre side.&lt;br /&gt;
&lt;br /&gt;
==Questasim==&lt;br /&gt;
&lt;br /&gt;
Start opp Questasim, lag nytt prosjekt og legg til vhdl fila (add_sub_alu.vhdl). Så legg vi til fila som Precision generte i prosjektdir til &#039;precision/prosjektnavn_temp_1/prosjektnavn.vhd&#039; (i vårt tilfelle &#039;alu/add_sub_alu_temp_1/add_sub_alu.vhd&#039;).&lt;br /&gt;
&lt;br /&gt;
Vi trenger simuleringsbibliotek for den valgte kretsfamilien for å kunne simulere etter &amp;quot;Place and Route&amp;quot;. Disse bibliotekene kan genereres fra Vivado med menyen&lt;br /&gt;
 Tools &amp;gt; Compile Simulation Libraries&lt;br /&gt;
men, vi har kompilert disse unisim-bibliotekene til mappen /eda/xilinx/lib. Du kan &amp;quot;mappe&amp;quot; disse slik:&lt;br /&gt;
&lt;br /&gt;
 vmap unisim /eda/xilinx/lib/unisim&lt;br /&gt;
 &lt;br /&gt;
Deretter legger vi til ei ny vhdl fil der vi skal lage testbenken vår. Vi legger til ein komponent av den opprinnelige og den synthesiserte vhdl koden. Vi koblar alle inngangane til samme signal på testbenken, og gir ut 2 forskjellige utsignal for å samanlikne ved hjelp av assert(sjå fila alu_tb.vhdl). På grunn av at utsignala av dei to komponentane ikkje skifta heilt synkront, testa vi berre kvart nanosekund ved å putta assert inn i ein process med wait for 1ns:&lt;br /&gt;
&lt;br /&gt;
 test : process&lt;br /&gt;
 begin&lt;br /&gt;
 wait for 1 ns;&lt;br /&gt;
 assert (data_out = data_out_synt)&lt;br /&gt;
 report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
 severity Error;&lt;br /&gt;
 end process test;&lt;br /&gt;
&lt;br /&gt;
Når vi har laga testbenken, kompilerer vi filene (husk å kompilere i rett rekkefølge med compileorder-&amp;gt;autogenerate første gong).&lt;br /&gt;
&lt;br /&gt;
Siden precision generer samme navn på entityen og architecturen på den syntetiserte filen som i den orginale så vil ikke simulatoren kjøre de samtidig. Dette endres ved å endre entity fra add_sub_alu til add_sub_alu_synth og skifte navnet på architecture fra algoritm til structure øverst og nederst i den syntetiserte filen.&lt;br /&gt;
&lt;br /&gt;
==Simulering med timing==&lt;br /&gt;
&lt;br /&gt;
Eksempel på start av simulering med timing:&lt;br /&gt;
&lt;br /&gt;
 vsim -t ps -sdfnoerror -sdfmax /alu_synth=/home/kaf003/VHDL_Prosjekter/PHYS321/vivado_impl_1/add_sub_alu_synth.sdf work.alu_tb&lt;br /&gt;
&lt;br /&gt;
Vi kan sjå at i dei første 50 nanosekunda er utsignala ulike. Dette er fordi før første klokkeflanke er verdiane udefinert i den opprinnelige komponenten, medan den synthesisere ikkje kan ha udefinerte verdiar. I Questasim vil vi derfor få ein del feilmeldingar dei første 50 nanosekunda.&lt;br /&gt;
&lt;br /&gt;
==Konklusjon==&lt;br /&gt;
&lt;br /&gt;
Vi kan teste om den syntesiserte komponenten oppfører seg likt med den opprinnelige komponenten ved å koble begge to til samme testbenk. Vi fekk problem i overgangane når vi testa kontinuerlig, så vi løyste problemet ved å berre teste kvart naonosekund. Bortsett frå dei første 50 nanosekunda (sjå grunn over) kan vi sjå at begge komponetane gir ut samme utsignal. Vi prøvde å bruke samme enitynavn på begge komponentane med ulik arcitechture, men fekk berre lov å kompilere og ikkje simulere. Vi kan derfor konkludere med at desse må ha ulike navn.&lt;br /&gt;
&lt;br /&gt;
==Kode==&lt;br /&gt;
&lt;br /&gt;
===Kode til add_sub_alu.vhd===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.All;&lt;br /&gt;
USE ieee.std_logic_unsigned.all;&lt;br /&gt;
&lt;br /&gt;
ENTITY add_sub_alu IS&lt;br /&gt;
PORT (&lt;br /&gt;
  clk         : IN  std_logic;&lt;br /&gt;
  rst         : IN  std_logic;&lt;br /&gt;
  enable_in   : IN  std_logic;&lt;br /&gt;
  start       : IN  std_logic;&lt;br /&gt;
  enable      : IN  std_logic;&lt;br /&gt;
  do_add      : IN  std_logic;&lt;br /&gt;
  do_subtract : IN  std_logic;&lt;br /&gt;
  do_hold     : IN  std_logic;&lt;br /&gt;
  data_in     : IN  std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  data_out    : OUT std_logic_vector(3 DOWNTO 0) BUS);&lt;br /&gt;
END add_sub_alu;&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE algorithm OF add_sub_alu IS&lt;br /&gt;
  TYPE   states          IS (hold, reset, add, subtract);&lt;br /&gt;
  SIGNAL state_var       : states;&lt;br /&gt;
  SIGNAL reg, int_reg    : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  SIGNAL latched_data_in : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
BEGIN&lt;br /&gt;
&lt;br /&gt;
latch: PROCESS (enable_in, data_in)is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (enable_in = &#039;1&#039;) THEN&lt;br /&gt;
    latched_data_in &amp;lt;= data_in;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS latch;&lt;br /&gt;
&lt;br /&gt;
fsm: PROCESS (clk, rst) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (rst = &#039;0&#039;) THEN&lt;br /&gt;
    state_var &amp;lt;= reset;&lt;br /&gt;
  ELSIF rising_edge(clk) THEN&lt;br /&gt;
    CASE state_var IS&lt;br /&gt;
      WHEN hold =&amp;gt;&lt;br /&gt;
        IF (start = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= reset;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN reset    =&amp;gt;&lt;br /&gt;
        IF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN add      =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN subtract =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN OTHERS =&amp;gt; state_var &amp;lt;= reset;&lt;br /&gt;
    END CASE;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS fsm;&lt;br /&gt;
&lt;br /&gt;
alu: PROCESS (state_var, latched_data_in, reg)is&lt;br /&gt;
BEGIN&lt;br /&gt;
CASE state_var IS&lt;br /&gt;
  WHEN add      =&amp;gt; int_reg &amp;lt;= reg + latched_data_in;&lt;br /&gt;
  WHEN subtract =&amp;gt; int_reg &amp;lt;= reg - latched_data_in;&lt;br /&gt;
  WHEN reset    =&amp;gt; int_reg &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
  WHEN hold     =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
  WHEN OTHERS   =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
END CASE;&lt;br /&gt;
END PROCESS alu;&lt;br /&gt;
&lt;br /&gt;
mem: PROCESS (clk) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF rising_edge(clk) THEN&lt;br /&gt;
    reg &amp;lt;= int_reg;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS mem;&lt;br /&gt;
&lt;br /&gt;
tri: PROCESS (enable, reg) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  FOR i IN 3 DOWNTO 0 LOOP&lt;br /&gt;
    IF (enable = &#039;1&#039;) THEN&lt;br /&gt;
      data_out(i) &amp;lt;= reg(i);&lt;br /&gt;
    ELSE&lt;br /&gt;
      data_out(i) &amp;lt;= &#039;Z&#039;;&lt;br /&gt;
    END IF;&lt;br /&gt;
  END LOOP;&lt;br /&gt;
END PROCESS tri;&lt;br /&gt;
&lt;br /&gt;
END algorithm;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Koden til alu_tb.vhdl===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library ieee;&lt;br /&gt;
use ieee.std_logic_1164.all;&lt;br /&gt;
library work;&lt;br /&gt;
use work.all;&lt;br /&gt;
&lt;br /&gt;
entity alu_tb is&lt;br /&gt;
end entity alu_tb;&lt;br /&gt;
&lt;br /&gt;
architecture struct of alu_tb is&lt;br /&gt;
  --Deklaring av signal som skal koblast til komponentane.&lt;br /&gt;
  --Alle innsignal er felles, medan vi har 2 forskjellige utsignal.&lt;br /&gt;
  signal clk           : std_logic;&lt;br /&gt;
  signal reset         : std_logic;&lt;br /&gt;
  signal enable_in     : std_logic;&lt;br /&gt;
  signal start         : std_logic;&lt;br /&gt;
  signal enable        : std_logic;&lt;br /&gt;
  signal do_add        : std_logic;&lt;br /&gt;
  signal do_subtract   : std_logic;&lt;br /&gt;
  signal do_hold       : std_logic;&lt;br /&gt;
  signal data_in       : std_logic_vector(3 downto 0);&lt;br /&gt;
  signal data_out      : std_logic_vector(3 downto 0);&lt;br /&gt;
  signal data_out_synt : std_logic_vector(3 downto 0);&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
  --Deklarer komponenten alu.&lt;br /&gt;
  alu : entity add_sub_alu(algorithm)&lt;br /&gt;
    --Kobler signala til den opprinnelige komponenten.&lt;br /&gt;
    port map (&lt;br /&gt;
    clk =&amp;gt; clk,&lt;br /&gt;
    rst =&amp;gt; reset,&lt;br /&gt;
    enable_in =&amp;gt; enable_in,&lt;br /&gt;
    start =&amp;gt; start,&lt;br /&gt;
    enable =&amp;gt; enable,&lt;br /&gt;
    do_add =&amp;gt; do_add,&lt;br /&gt;
    do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
    do_hold =&amp;gt; do_hold,&lt;br /&gt;
    data_in =&amp;gt; data_in,&lt;br /&gt;
    data_out =&amp;gt; data_out);&lt;br /&gt;
&lt;br /&gt;
  --Deklarer komponenten alu_synt.&lt;br /&gt;
  alu_synt : entity add_sub_alu_synth(structure)&lt;br /&gt;
  --Kobler signala til den synthiserte komponenten.&lt;br /&gt;
    port map (&lt;br /&gt;
    clk =&amp;gt; clk,&lt;br /&gt;
    rst =&amp;gt; reset,&lt;br /&gt;
    enable_in =&amp;gt; enable_in,&lt;br /&gt;
    start =&amp;gt; start,&lt;br /&gt;
    enable =&amp;gt; enable,&lt;br /&gt;
    do_add =&amp;gt; do_add,&lt;br /&gt;
    do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
    do_hold =&amp;gt; do_hold,&lt;br /&gt;
    data_in =&amp;gt; data_in,&lt;br /&gt;
    data_out =&amp;gt; data_out_synt);&lt;br /&gt;
&lt;br /&gt;
  --Klokkegenerator&lt;br /&gt;
  clock_gen : process&lt;br /&gt;
    begin&lt;br /&gt;
    clk &amp;lt;= &#039;0&#039;, &#039;1&#039; after 50 ns;&lt;br /&gt;
    wait for 100 ns;&lt;br /&gt;
  end process clock_gen;&lt;br /&gt;
&lt;br /&gt;
  --Setter testvektorane.&lt;br /&gt;
  reset &amp;lt;= &#039;0&#039;, &#039;1&#039; after 60 ns;&lt;br /&gt;
  enable &amp;lt;= &#039;1&#039;, &#039;0&#039; after 900 ns;&lt;br /&gt;
  enable_in &amp;lt;= &#039;1&#039;, &#039;0&#039; after 400 ns;&lt;br /&gt;
  start &amp;lt;= &#039;1&#039;, &#039;0&#039; after 300 ns;&lt;br /&gt;
  do_add &amp;lt;= &#039;1&#039;, &#039;0&#039; after 660 ns;&lt;br /&gt;
  do_subtract &amp;lt;= &#039;0&#039;;&lt;br /&gt;
  do_hold &amp;lt;= &#039;0&#039;;&lt;br /&gt;
  data_in &amp;lt;= X&amp;quot;3&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  --Test process for å samanlikne utsignala kvart nanosekund.&lt;br /&gt;
  test : process&lt;br /&gt;
  begin&lt;br /&gt;
  wait for 1 ns;&lt;br /&gt;
  assert (data_out = data_out_synt)&lt;br /&gt;
  report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
  severity Error;&lt;br /&gt;
  end process test;&lt;br /&gt;
&lt;br /&gt;
end architecture struct;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Simulering_av_VHDL&amp;diff=2901</id>
		<title>Simulering av VHDL</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Simulering_av_VHDL&amp;diff=2901"/>
		<updated>2024-01-24T07:54:24Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: /* Starte Questa Sim */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Konstruksjon og simulering av VHDL-kode med Modelsim/Questa===&lt;br /&gt;
&lt;br /&gt;
==Innledning==&lt;br /&gt;
&lt;br /&gt;
Hensikten med denne oppgaven er å få et lite innblikk i bruk av høynivåspråk for simulering og uttesting av kretsløsninger. I denne oppgaven skal vi bruker VHDL (Very high speed integrated circuit Hardware Description Language), som er spesielt utviklet for elektronikk. VHDL er definert slik at det passer i en mengde sammenhenger, og er det vil derfor være uoverkommelig å gå inn på detaljer i denne oppgaven. Vi skal ta for oss noen eksempler:&lt;br /&gt;
&lt;br /&gt;
* Eksempel 1: Signalflyt i en SR-lås&lt;br /&gt;
&lt;br /&gt;
* Eksempel 2: Signaler og variable&lt;br /&gt;
&lt;br /&gt;
Et VHDL program består i hovedsak av ENTITY, som definerer tilkobling mellom programmet og omverden, og ARCHITECTURE, som definerer programmets funksjon. Den komplette VHDL-koden for eksempel 1 vist nederst på denne siden.Mentor Graphics har utviklet programvare (Modelsim//Questa) som gjør det mulig å beskrivem, simulere og feilsøke VHDL-kode. Fremgangsmåten for skriving, kompilering og simulering av VHDL-kode finner du under.&lt;br /&gt;
&lt;br /&gt;
==Starte Questa Sim==&lt;br /&gt;
Når man skal arbeide med Questa Sim fra Mentor Graphics skriv følgende kommando i et terminalvindu.&lt;br /&gt;
Generelt ligger programvaren i /eda/Siemens, og versjonene ligger i mapper sortert på årstall.&lt;br /&gt;
&lt;br /&gt;
 ssh -X mikroserver4&lt;br /&gt;
 export LM_LICENSE_FILE=1717@lisensserver&lt;br /&gt;
 source /eda/Siemens/2023-24/scripts/QUESTA-CORE-PRIME_2023.4_RHELx86.sh&lt;br /&gt;
 vsim&lt;br /&gt;
&lt;br /&gt;
==Lage et nytt prosjekt==&lt;br /&gt;
&lt;br /&gt;
I den følgende teksten er det vist hvordan man kan utføre kompilering, etc. på kommandolinjen. Dette kan enten gjøres i fra X terminalvinduet, eller fra kommandolinjen i Questa. Hvis man velger å bruke Questa-miljøet er de fleste prosedyrer/kommandoer tilgjengelige under menyen.&lt;br /&gt;
&lt;br /&gt;
Start et nytt prosjekt med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
File &amp;gt; New &amp;gt; Project&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:questa_new_project.png]]&lt;br /&gt;
&lt;br /&gt;
Velg et fornuftig navn og katalog. Man kan gjerne ha flere uavhengige vhdl-filer i et prosjekt.&lt;br /&gt;
Det er en fordel å ha en hovedkatalog til vhdl prosjektene og en underkatalog for prosjektet fex /home/bruker/vhdl_prosjekt/sr_latch&lt;br /&gt;
&lt;br /&gt;
==Skriving av VHDL kode==&lt;br /&gt;
&lt;br /&gt;
En ny VHDL kode (et design beskrevet med VHDL kode) påbegynnes med å starte emacs i terminal vinduet eller ved å bruke den innebygde teksteditoren i Questa ved å velge Create New File. &lt;br /&gt;
&lt;br /&gt;
Det fine med emacs er at man kan velge VHDL-modus. Dette gjøres med å skrive &#039;&#039;M-x vhdl-mode&#039;&#039; (M står for &#039;&#039;Meta&#039;&#039; og er vanligvis definert som esc-knappen). I emacs har en menyer med alle valg oppe langs kanten som i andre teksteditorer, men programmet skiller seg litt ut med kommandolinjen nederst i vinduet. Når en f. eks. skal lagre filen en har skrevet blir denne kommandolinjen aktiv og en skriver inn sti og filnavn der. Når man lagrer er ikke navnet på kodefilen viktig, men det er fornuftig å kalle den det samme som ENTITY-delen, med &#039;&#039;.vhdl&#039;&#039; som &amp;quot;etternavn&amp;quot; (f. eks. sr_latch.vhdl).&lt;br /&gt;
&lt;br /&gt;
==Kompilering av VHDL kode==&lt;br /&gt;
&lt;br /&gt;
Koden kompileres med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vcom sr_latch.vhdl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hvis det er feil i koden vil det komme en melding i kommando vinduet. Dobbeltklikker du på feilen vil du få opp en liste over kompileringsprosessen og alle feilene. Dobbeltklikker du så på linjen som angir en feil så vises den respektive linjen i editoren.&lt;br /&gt;
&lt;br /&gt;
Merk at navnet til det kompilerte designet blir skrevet med små bokstaver, selv om du har brukt store bokstaver i ENTITY- eller ARCHITECTURE-navnet. Det kompilerte designet blir liggende i work-katalogen.&lt;br /&gt;
&lt;br /&gt;
==Simulering og debugging i Questa==&lt;br /&gt;
&lt;br /&gt;
Når koden kompilerer feilfritt kan den simuleres i Questa. Dette startes med:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vsim&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nå dukker det opp en rute der du skal velge hva som skal simuleres, utvid work og velg vhdl filen. Eventuellt kan du skrive vsim work.sr_latch i kommandovinduet&lt;br /&gt;
&lt;br /&gt;
Questa bruker et standard X-basert vindusoppsett, og er derfor noen forskjellig fra de andre Mentor-programmene. Når du starter simulatoren åpnes det et vindu som vist i figur 1. Begynn med å åpne diverse vinduer:&lt;br /&gt;
&lt;br /&gt;
* View &amp;gt; Wave&lt;br /&gt;
&lt;br /&gt;
* View &amp;gt; Objects&lt;br /&gt;
&lt;br /&gt;
* View &amp;gt; Locals&lt;br /&gt;
&lt;br /&gt;
Man kan også gi kommandoer i Questa-vinduet. F.eks.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Wave *&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dra de signalene du vil se på i wave vinduet fra object vinduet.&lt;br /&gt;
&lt;br /&gt;
Signalverdier settes med kommandoen &#039;force&#039; eller med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Force &amp;gt; Force (i &amp;quot;Signals&amp;quot; vinduet)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dersom et av signalene skal være klokkesignal, kan dette gjøres enkelt med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Force &amp;gt; Clock (i &amp;quot;Signals&amp;quot; vinduet)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Eksempler==&lt;br /&gt;
===Signalflyt i en SR-lås===&lt;br /&gt;
&lt;br /&gt;
Simuler SR-låsen. Begynn med å påtrykke stimuli til alle signaler ved tid 0 (t0). Bruk STEP-knappen for å simulere på delta-tid-nivå. (Om en holder musepekeren over knappene i Questa, kommer det en forklarende tekst opp.) Når verdiene er stabile kjører du i f.eks. 100 ns før du endrer stimuli (skriv &#039;&#039;run 100&#039;&#039; i et av vinduene). Tilsvarende kan du endre stimuli ved å skrive f.eks. &#039;&#039;force S 0&#039;&#039; i hoved-vinduet. Legg merke til den røde pilen som peker på den linjen som blir utført.&lt;br /&gt;
&lt;br /&gt;
Hvis du vil begynne på ny kan du velge&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
File &amp;gt; Restart -f&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.ALL;&lt;br /&gt;
&lt;br /&gt;
ENTITY SR_latch IS&lt;br /&gt;
PORT (&lt;br /&gt;
S,R  : IN std_logic ;&lt;br /&gt;
Q,QB : INOUT std_logic );&lt;br /&gt;
END SR_latch;&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE behave OF SR_latch IS&lt;br /&gt;
&lt;br /&gt;
BEGIN  --  behave&lt;br /&gt;
Q &amp;lt;= S nand QB;&lt;br /&gt;
QB &amp;lt;= R nand Q;&lt;br /&gt;
END behave;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Signaler og variable===&lt;br /&gt;
&lt;br /&gt;
Simuler VHDL-koden under. Bruk Step eller Step Over for å følge prosedyrens utvikling linje for linje. Simulere med optimaliseringsopsjon &amp;quot;-voptargs=+acc&amp;quot; for å kunne se variablene i wave-vinduet:&lt;br /&gt;
&lt;br /&gt;
 vsim -voptargs=+acc sign_var&lt;br /&gt;
&lt;br /&gt;
Bruk View &amp;gt; Objects for å kikke på signalene og View &amp;gt; Local for å se innholdet i variablene. Forklar endringene i signaler og variable. Hva er forskjellen som funksjon av tid/delta-tid?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.ALL;&lt;br /&gt;
&lt;br /&gt;
ENTITY sign_var IS&lt;br /&gt;
  PORT (clk  : IN std_logic);&lt;br /&gt;
END sign_var;&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE difference OF sign_var IS&lt;br /&gt;
&lt;br /&gt;
signal SA: bit := &#039;0&#039;;&lt;br /&gt;
signal SB: bit := &#039;1&#039;;&lt;br /&gt;
&lt;br /&gt;
begin  --  difference&lt;br /&gt;
p_test: process&lt;br /&gt;
  variable A: bit := &#039;0&#039;;&lt;br /&gt;
  variable B: bit := &#039;1&#039;;&lt;br /&gt;
  begin&lt;br /&gt;
    wait until rising_edge(clk);&lt;br /&gt;
    A := B;&lt;br /&gt;
    B := A;&lt;br /&gt;
    SA &amp;lt;= SB after 5 ns;&lt;br /&gt;
    SB &amp;lt;= SA after 5 ns;&lt;br /&gt;
  end process p_test;&lt;br /&gt;
end architecture difference;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2819</id>
		<title>Synthese av VHDL</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2819"/>
		<updated>2021-02-05T13:44:45Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: oppdatert sdf-inkludering med sdfnoerror&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Syntetiseringen av VHDL kode===&lt;br /&gt;
&lt;br /&gt;
Grunnen til at vi skal syntetisere koden, er at vi må lage beskrivelse av koden tilpassa ein krets.&lt;br /&gt;
&lt;br /&gt;
Vi vil no prøve å synthesisere vhdl kode. Og etterpå vil vi lage ein testbenk der vi samanliknar utsignala frå den syntetiserte og den opprinnelige koden. Vi bruker ein alu som eksempel.&lt;br /&gt;
&lt;br /&gt;
==Precision==&lt;br /&gt;
&lt;br /&gt;
Precision bruker Vivado til å syntetisere vhdl-koden. For å starte synteseprogrammet:&lt;br /&gt;
&lt;br /&gt;
 export LM_LICENSE_FILE=1717@lisensserver:2100@lisensserver&lt;br /&gt;
 source /eda/mentor/2019-20/scripts/PRECISION_2019.1.1_RHELx86.sh&lt;br /&gt;
 precision&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Vel deretter New Project, og deretter Add input file (i dette tilfelle add_sub_alu.vhd).&lt;br /&gt;
Så går vi inn på Setup design, velger ein kretsprodusent, den ønska kretsen og designfrekvens, for eksempel Zynq med frekvens 200MHz. For å få ut en vhdl fil av den syntetiserte koden må en gå på Tools-&amp;gt;Options-&amp;gt;Output og hak av for VHDL og trykk ok.&lt;br /&gt;
&lt;br /&gt;
Pass på at Precision finner Vivado, settes i menyen:&lt;br /&gt;
 Tools &amp;gt; Options &amp;gt; Place and Route Settings&lt;br /&gt;
deretter&lt;br /&gt;
 Vivado &amp;gt; Integrated Place and Route &amp;gt; path to Xilinx Vivado installation tree&lt;br /&gt;
settes til&lt;br /&gt;
 /eda/xilinx/Vivado/2020.2&lt;br /&gt;
&lt;br /&gt;
Trykk så compile, og synthesize. &lt;br /&gt;
No kan vi sjå på den generte kretsen i RTL Schematic og Technology Schematic (syntese med den valgte kretsen) under Schematics på venstre side.&lt;br /&gt;
&lt;br /&gt;
==Questasim==&lt;br /&gt;
&lt;br /&gt;
Start opp Questasim, lag nytt prosjekt og legg til vhdl fila (add_sub_alu.vhdl). Så legg vi til fila som Precision generte i prosjektdir til &#039;precision/prosjektnavn_temp_1/prosjektnavn.vhd&#039; (i vårt tilfelle &#039;alu/add_sub_alu_temp_1/add_sub_alu.vhd&#039;).&lt;br /&gt;
&lt;br /&gt;
Vi trenger simuleringsbibliotek for den valgte kretsfamilien for å kunne simulere etter &amp;quot;Place and Route&amp;quot;. Disse bibliotekene kan genereres fra Vivado med menyen&lt;br /&gt;
 Tools &amp;gt; Compile Simulation Libraries&lt;br /&gt;
men, vi har kompilert disse unisim-bibliotekene til mappen /eda/xilinx/lib. Du kan &amp;quot;mappe&amp;quot; disse slik:&lt;br /&gt;
&lt;br /&gt;
 vmap unisim /eda/xilinx/lib/unisim&lt;br /&gt;
 &lt;br /&gt;
Deretter legger vi til ei ny vhdl fil der vi skal lage testbenken vår. Vi legger til ein komponent av den opprinnelige og den synthesiserte vhdl koden. Vi koblar alle inngangane til samme signal på testbenken, og gir ut 2 forskjellige utsignal for å samanlikne ved hjelp av assert(sjå fila alu_tb.vhdl). På grunn av at utsignala av dei to komponentane ikkje skifta heilt synkront, testa vi berre kvart nanosekund ved å putta assert inn i ein process med wait for 1ns:&lt;br /&gt;
&lt;br /&gt;
 test : process&lt;br /&gt;
 begin&lt;br /&gt;
 wait for 1 ns;&lt;br /&gt;
 assert (data_out = data_out_synt)&lt;br /&gt;
 report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
 severity Error;&lt;br /&gt;
 end process test;&lt;br /&gt;
&lt;br /&gt;
Når vi har laga testbenken, kompilerer vi filene (husk å kompilere i rett rekkefølge med compileorder-&amp;gt;autogenerate første gong).&lt;br /&gt;
&lt;br /&gt;
Siden precision generer samme navn på entityen og architecturen på den syntetiserte filen som i den orginale så vil ikke simulatoren kjøre de samtidig. Dette endres ved å endre entity fra add_sub_alu til add_sub_alu_synth og skifte navnet på architecture fra algoritm til structure øverst og nederst i den syntetiserte filen.&lt;br /&gt;
&lt;br /&gt;
==Simulering med timing==&lt;br /&gt;
&lt;br /&gt;
Eksempel på start av simulering med timing:&lt;br /&gt;
&lt;br /&gt;
 vsim -t ps -sdfnoerror -sdfmax /alu_synth=/home/kaf003/VHDL_Prosjekter/PHYS321/vivado_impl_1/add_sub_alu_synth.sdf work.alu_tb&lt;br /&gt;
&lt;br /&gt;
Vi kan sjå at i dei første 50 nanosekunda er utsignala ulike. Dette er fordi før første klokkeflanke er verdiane udefinert i den opprinnelige komponenten, medan den synthesisere ikkje kan ha udefinerte verdiar. I Questasim vil vi derfor få ein del feilmeldingar dei første 50 nanosekunda.&lt;br /&gt;
&lt;br /&gt;
==Konklusjon==&lt;br /&gt;
&lt;br /&gt;
Vi kan teste om den syntesiserte komponenten oppfører seg likt med den opprinnelige komponenten ved å koble begge to til samme testbenk. Vi fekk problem i overgangane når vi testa kontinuerlig, så vi løyste problemet ved å berre teste kvart naonosekund. Bortsett frå dei første 50 nanosekunda (sjå grunn over) kan vi sjå at begge komponetane gir ut samme utsignal. Vi prøvde å bruke samme enitynavn på begge komponentane med ulik arcitechture, men fekk berre lov å kompilere og ikkje simulere. Vi kan derfor konkludere med at desse må ha ulike navn.&lt;br /&gt;
&lt;br /&gt;
==Kode==&lt;br /&gt;
&lt;br /&gt;
===Kode til add_sub_alu.vhd===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.All;&lt;br /&gt;
USE ieee.std_logic_unsigned.all;&lt;br /&gt;
&lt;br /&gt;
ENTITY add_sub_alu IS&lt;br /&gt;
PORT (&lt;br /&gt;
  clk         : IN  std_logic;&lt;br /&gt;
  rst         : IN  std_logic;&lt;br /&gt;
  enable_in   : IN  std_logic;&lt;br /&gt;
  start       : IN  std_logic;&lt;br /&gt;
  enable      : IN  std_logic;&lt;br /&gt;
  do_add      : IN  std_logic;&lt;br /&gt;
  do_subtract : IN  std_logic;&lt;br /&gt;
  do_hold     : IN  std_logic;&lt;br /&gt;
  data_in     : IN  std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  data_out    : OUT std_logic_vector(3 DOWNTO 0) BUS);&lt;br /&gt;
END add_sub_alu;&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE algorithm OF add_sub_alu IS&lt;br /&gt;
  TYPE   states          IS (hold, reset, add, subtract);&lt;br /&gt;
  SIGNAL state_var       : states;&lt;br /&gt;
  SIGNAL reg, int_reg    : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  SIGNAL latched_data_in : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
BEGIN&lt;br /&gt;
&lt;br /&gt;
latch: PROCESS (enable_in, data_in)is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (enable_in = &#039;1&#039;) THEN&lt;br /&gt;
    latched_data_in &amp;lt;= data_in;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS latch;&lt;br /&gt;
&lt;br /&gt;
fsm: PROCESS (clk, rst) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (rst = &#039;0&#039;) THEN&lt;br /&gt;
    state_var &amp;lt;= reset;&lt;br /&gt;
  ELSIF rising_edge(clk) THEN&lt;br /&gt;
    CASE state_var IS&lt;br /&gt;
      WHEN hold =&amp;gt;&lt;br /&gt;
        IF (start = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= reset;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN reset    =&amp;gt;&lt;br /&gt;
        IF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN add      =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN subtract =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN OTHERS =&amp;gt; state_var &amp;lt;= reset;&lt;br /&gt;
    END CASE;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS fsm;&lt;br /&gt;
&lt;br /&gt;
alu: PROCESS (state_var, latched_data_in, reg)is&lt;br /&gt;
BEGIN&lt;br /&gt;
CASE state_var IS&lt;br /&gt;
  WHEN add      =&amp;gt; int_reg &amp;lt;= reg + latched_data_in;&lt;br /&gt;
  WHEN subtract =&amp;gt; int_reg &amp;lt;= reg - latched_data_in;&lt;br /&gt;
  WHEN reset    =&amp;gt; int_reg &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
  WHEN hold     =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
  WHEN OTHERS   =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
END CASE;&lt;br /&gt;
END PROCESS alu;&lt;br /&gt;
&lt;br /&gt;
mem: PROCESS (clk) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF rising_edge(clk) THEN&lt;br /&gt;
    reg &amp;lt;= int_reg;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS mem;&lt;br /&gt;
&lt;br /&gt;
tri: PROCESS (enable, reg) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  FOR i IN 3 DOWNTO 0 LOOP&lt;br /&gt;
    IF (enable = &#039;1&#039;) THEN&lt;br /&gt;
      data_out(i) &amp;lt;= reg(i);&lt;br /&gt;
    ELSE&lt;br /&gt;
      data_out(i) &amp;lt;= &#039;Z&#039;;&lt;br /&gt;
    END IF;&lt;br /&gt;
  END LOOP;&lt;br /&gt;
END PROCESS tri;&lt;br /&gt;
&lt;br /&gt;
END algorithm;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Koden til alu_tb.vhdl===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library ieee;&lt;br /&gt;
use ieee.std_logic_1164.all;&lt;br /&gt;
library work;&lt;br /&gt;
use work.all;&lt;br /&gt;
&lt;br /&gt;
entity alu_tb is&lt;br /&gt;
end entity alu_tb;&lt;br /&gt;
&lt;br /&gt;
architecture struct of alu_tb is&lt;br /&gt;
  --Deklaring av signal som skal koblast til komponentane.&lt;br /&gt;
  --Alle innsignal er felles, medan vi har 2 forskjellige utsignal.&lt;br /&gt;
  signal clk           : std_logic;&lt;br /&gt;
  signal reset         : std_logic;&lt;br /&gt;
  signal enable_in     : std_logic;&lt;br /&gt;
  signal start         : std_logic;&lt;br /&gt;
  signal enable        : std_logic;&lt;br /&gt;
  signal do_add        : std_logic;&lt;br /&gt;
  signal do_subtract   : std_logic;&lt;br /&gt;
  signal do_hold       : std_logic;&lt;br /&gt;
  signal data_in       : std_logic_vector(3 downto 0);&lt;br /&gt;
  signal data_out      : std_logic_vector(3 downto 0);&lt;br /&gt;
  signal data_out_synt : std_logic_vector(3 downto 0);&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
  --Deklarer komponenten alu.&lt;br /&gt;
  alu : entity add_sub_alu(algorithm)&lt;br /&gt;
    --Kobler signala til den opprinnelige komponenten.&lt;br /&gt;
    port map (&lt;br /&gt;
    clk =&amp;gt; clk,&lt;br /&gt;
    rst =&amp;gt; reset,&lt;br /&gt;
    enable_in =&amp;gt; enable_in,&lt;br /&gt;
    start =&amp;gt; start,&lt;br /&gt;
    enable =&amp;gt; enable,&lt;br /&gt;
    do_add =&amp;gt; do_add,&lt;br /&gt;
    do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
    do_hold =&amp;gt; do_hold,&lt;br /&gt;
    data_in =&amp;gt; data_in,&lt;br /&gt;
    data_out =&amp;gt; data_out);&lt;br /&gt;
&lt;br /&gt;
  --Deklarer komponenten alu_synt.&lt;br /&gt;
  alu_synt : entity add_sub_alu_synth(structure)&lt;br /&gt;
  --Kobler signala til den synthiserte komponenten.&lt;br /&gt;
    port map (&lt;br /&gt;
    clk =&amp;gt; clk,&lt;br /&gt;
    rst =&amp;gt; reset,&lt;br /&gt;
    enable_in =&amp;gt; enable_in,&lt;br /&gt;
    start =&amp;gt; start,&lt;br /&gt;
    enable =&amp;gt; enable,&lt;br /&gt;
    do_add =&amp;gt; do_add,&lt;br /&gt;
    do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
    do_hold =&amp;gt; do_hold,&lt;br /&gt;
    data_in =&amp;gt; data_in,&lt;br /&gt;
    data_out =&amp;gt; data_out_synt);&lt;br /&gt;
&lt;br /&gt;
  --Klokkegenerator&lt;br /&gt;
  clock_gen : process&lt;br /&gt;
    begin&lt;br /&gt;
    clk &amp;lt;= &#039;0&#039;, &#039;1&#039; after 50 ns;&lt;br /&gt;
    wait for 100 ns;&lt;br /&gt;
  end process clock_gen;&lt;br /&gt;
&lt;br /&gt;
  --Setter testvektorane.&lt;br /&gt;
  reset &amp;lt;= &#039;0&#039;, &#039;1&#039; after 60 ns;&lt;br /&gt;
  enable &amp;lt;= &#039;1&#039;, &#039;0&#039; after 900 ns;&lt;br /&gt;
  enable_in &amp;lt;= &#039;1&#039;, &#039;0&#039; after 400 ns;&lt;br /&gt;
  start &amp;lt;= &#039;1&#039;, &#039;0&#039; after 300 ns;&lt;br /&gt;
  do_add &amp;lt;= &#039;1&#039;, &#039;0&#039; after 660 ns;&lt;br /&gt;
  do_subtract &amp;lt;= &#039;0&#039;;&lt;br /&gt;
  do_hold &amp;lt;= &#039;0&#039;;&lt;br /&gt;
  data_in &amp;lt;= X&amp;quot;3&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  --Test process for å samanlikne utsignala kvart nanosekund.&lt;br /&gt;
  test : process&lt;br /&gt;
  begin&lt;br /&gt;
  wait for 1 ns;&lt;br /&gt;
  assert (data_out = data_out_synt)&lt;br /&gt;
  report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
  severity Error;&lt;br /&gt;
  end process test;&lt;br /&gt;
&lt;br /&gt;
end architecture struct;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2818</id>
		<title>Synthese av VHDL</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2818"/>
		<updated>2021-02-05T12:10:31Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: /* Koden til alu_tb.vhdl */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Syntetiseringen av VHDL kode===&lt;br /&gt;
&lt;br /&gt;
Grunnen til at vi skal syntetisere koden, er at vi må lage beskrivelse av koden tilpassa ein krets.&lt;br /&gt;
&lt;br /&gt;
Vi vil no prøve å synthesisere vhdl kode. Og etterpå vil vi lage ein testbenk der vi samanliknar utsignala frå den syntetiserte og den opprinnelige koden. Vi bruker ein alu som eksempel.&lt;br /&gt;
&lt;br /&gt;
==Precision==&lt;br /&gt;
&lt;br /&gt;
Precision bruker Vivado til å syntetisere vhdl-koden. For å starte synteseprogrammet:&lt;br /&gt;
&lt;br /&gt;
 export LM_LICENSE_FILE=1717@lisensserver:2100@lisensserver&lt;br /&gt;
 source /eda/mentor/2019-20/scripts/PRECISION_2019.1.1_RHELx86.sh&lt;br /&gt;
 precision&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Vel deretter New Project, og deretter Add input file (i dette tilfelle add_sub_alu.vhd).&lt;br /&gt;
Så går vi inn på Setup design, velger ein kretsprodusent, den ønska kretsen og designfrekvens, for eksempel Zynq med frekvens 200MHz. For å få ut en vhdl fil av den syntetiserte koden må en gå på Tools-&amp;gt;Options-&amp;gt;Output og hak av for VHDL og trykk ok.&lt;br /&gt;
&lt;br /&gt;
Pass på at Precision finner Vivado, settes i menyen:&lt;br /&gt;
 Tools &amp;gt; Options &amp;gt; Place and Route Settings&lt;br /&gt;
deretter&lt;br /&gt;
 Vivado &amp;gt; Integrated Place and Route &amp;gt; path to Xilinx Vivado installation tree&lt;br /&gt;
settes til&lt;br /&gt;
 /eda/xilinx/Vivado/2020.2&lt;br /&gt;
&lt;br /&gt;
Trykk så compile, og synthesize. &lt;br /&gt;
No kan vi sjå på den generte kretsen i RTL Schematic og Technology Schematic (syntese med den valgte kretsen) under Schematics på venstre side.&lt;br /&gt;
&lt;br /&gt;
==Questasim==&lt;br /&gt;
&lt;br /&gt;
Start opp Questasim, lag nytt prosjekt og legg til vhdl fila (add_sub_alu.vhdl). Så legg vi til fila som Precision generte i prosjektdir til &#039;precision/prosjektnavn_temp_1/prosjektnavn.vhd&#039; (i vårt tilfelle &#039;alu/add_sub_alu_temp_1/add_sub_alu.vhd&#039;).&lt;br /&gt;
&lt;br /&gt;
Vi trenger simuleringsbibliotek for den valgte kretsfamilien for å kunne simulere etter &amp;quot;Place and Route&amp;quot;. Disse bibliotekene kan genereres fra Vivado med menyen&lt;br /&gt;
 Tools &amp;gt; Compile Simulation Libraries&lt;br /&gt;
men, vi har kompilert disse unisim-bibliotekene til mappen /eda/xilinx/lib. Du kan &amp;quot;mappe&amp;quot; disse slik:&lt;br /&gt;
&lt;br /&gt;
 vmap unisim /eda/xilinx/lib/unisim&lt;br /&gt;
 &lt;br /&gt;
Deretter legger vi til ei ny vhdl fil der vi skal lage testbenken vår. Vi legger til ein komponent av den opprinnelige og den synthesiserte vhdl koden. Vi koblar alle inngangane til samme signal på testbenken, og gir ut 2 forskjellige utsignal for å samanlikne ved hjelp av assert(sjå fila alu_tb.vhdl). På grunn av at utsignala av dei to komponentane ikkje skifta heilt synkront, testa vi berre kvart nanosekund ved å putta assert inn i ein process med wait for 1ns:&lt;br /&gt;
&lt;br /&gt;
 test : process&lt;br /&gt;
 begin&lt;br /&gt;
 wait for 1 ns;&lt;br /&gt;
 assert (data_out = data_out_synt)&lt;br /&gt;
 report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
 severity Error;&lt;br /&gt;
 end process test;&lt;br /&gt;
&lt;br /&gt;
Når vi har laga testbenken, kompilerer vi filene (husk å kompilere i rett rekkefølge med compileorder-&amp;gt;autogenerate første gong).&lt;br /&gt;
&lt;br /&gt;
Siden precision generer samme navn på entityen og architecturen på den syntetiserte filen som i den orginale så vil ikke simulatoren kjøre de samtidig. Dette endres ved å endre entity fra add_sub_alu til add_sub_alu_synth og skifte navnet på architecture fra algoritm til structure øverst og nederst i den syntetiserte filen.&lt;br /&gt;
&lt;br /&gt;
==Simulering med timing==&lt;br /&gt;
&lt;br /&gt;
Eksempel på start av simulering med timing:&lt;br /&gt;
&lt;br /&gt;
 vsim -t ps alu_tb -sdfmax :alu_tb:ali=/heim/yngve/vhdl/syntese/alu_temp_1/simulation/modelsim/add_sub_alu_vhd.sdo&lt;br /&gt;
&lt;br /&gt;
Vi kan sjå at i dei første 50 nanosekunda er utsignala ulike. Dette er fordi før første klokkeflanke er verdiane udefinert i den opprinnelige komponenten, medan den synthesisere ikkje kan ha udefinerte verdiar. I Questasim vil vi derfor få ein del feilmeldingar dei første 50 nanosekunda.&lt;br /&gt;
&lt;br /&gt;
==Konklusjon==&lt;br /&gt;
&lt;br /&gt;
Vi kan teste om den syntesiserte komponenten oppfører seg likt med den opprinnelige komponenten ved å koble begge to til samme testbenk. Vi fekk problem i overgangane når vi testa kontinuerlig, så vi løyste problemet ved å berre teste kvart naonosekund. Bortsett frå dei første 50 nanosekunda (sjå grunn over) kan vi sjå at begge komponetane gir ut samme utsignal. Vi prøvde å bruke samme enitynavn på begge komponentane med ulik arcitechture, men fekk berre lov å kompilere og ikkje simulere. Vi kan derfor konkludere med at desse må ha ulike navn.&lt;br /&gt;
&lt;br /&gt;
==Kode==&lt;br /&gt;
&lt;br /&gt;
===Kode til add_sub_alu.vhd===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.All;&lt;br /&gt;
USE ieee.std_logic_unsigned.all;&lt;br /&gt;
&lt;br /&gt;
ENTITY add_sub_alu IS&lt;br /&gt;
PORT (&lt;br /&gt;
  clk         : IN  std_logic;&lt;br /&gt;
  rst         : IN  std_logic;&lt;br /&gt;
  enable_in   : IN  std_logic;&lt;br /&gt;
  start       : IN  std_logic;&lt;br /&gt;
  enable      : IN  std_logic;&lt;br /&gt;
  do_add      : IN  std_logic;&lt;br /&gt;
  do_subtract : IN  std_logic;&lt;br /&gt;
  do_hold     : IN  std_logic;&lt;br /&gt;
  data_in     : IN  std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  data_out    : OUT std_logic_vector(3 DOWNTO 0) BUS);&lt;br /&gt;
END add_sub_alu;&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE algorithm OF add_sub_alu IS&lt;br /&gt;
  TYPE   states          IS (hold, reset, add, subtract);&lt;br /&gt;
  SIGNAL state_var       : states;&lt;br /&gt;
  SIGNAL reg, int_reg    : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  SIGNAL latched_data_in : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
BEGIN&lt;br /&gt;
&lt;br /&gt;
latch: PROCESS (enable_in, data_in)is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (enable_in = &#039;1&#039;) THEN&lt;br /&gt;
    latched_data_in &amp;lt;= data_in;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS latch;&lt;br /&gt;
&lt;br /&gt;
fsm: PROCESS (clk, rst) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (rst = &#039;0&#039;) THEN&lt;br /&gt;
    state_var &amp;lt;= reset;&lt;br /&gt;
  ELSIF rising_edge(clk) THEN&lt;br /&gt;
    CASE state_var IS&lt;br /&gt;
      WHEN hold =&amp;gt;&lt;br /&gt;
        IF (start = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= reset;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN reset    =&amp;gt;&lt;br /&gt;
        IF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN add      =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN subtract =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN OTHERS =&amp;gt; state_var &amp;lt;= reset;&lt;br /&gt;
    END CASE;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS fsm;&lt;br /&gt;
&lt;br /&gt;
alu: PROCESS (state_var, latched_data_in, reg)is&lt;br /&gt;
BEGIN&lt;br /&gt;
CASE state_var IS&lt;br /&gt;
  WHEN add      =&amp;gt; int_reg &amp;lt;= reg + latched_data_in;&lt;br /&gt;
  WHEN subtract =&amp;gt; int_reg &amp;lt;= reg - latched_data_in;&lt;br /&gt;
  WHEN reset    =&amp;gt; int_reg &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
  WHEN hold     =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
  WHEN OTHERS   =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
END CASE;&lt;br /&gt;
END PROCESS alu;&lt;br /&gt;
&lt;br /&gt;
mem: PROCESS (clk) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF rising_edge(clk) THEN&lt;br /&gt;
    reg &amp;lt;= int_reg;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS mem;&lt;br /&gt;
&lt;br /&gt;
tri: PROCESS (enable, reg) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  FOR i IN 3 DOWNTO 0 LOOP&lt;br /&gt;
    IF (enable = &#039;1&#039;) THEN&lt;br /&gt;
      data_out(i) &amp;lt;= reg(i);&lt;br /&gt;
    ELSE&lt;br /&gt;
      data_out(i) &amp;lt;= &#039;Z&#039;;&lt;br /&gt;
    END IF;&lt;br /&gt;
  END LOOP;&lt;br /&gt;
END PROCESS tri;&lt;br /&gt;
&lt;br /&gt;
END algorithm;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Koden til alu_tb.vhdl===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library ieee;&lt;br /&gt;
use ieee.std_logic_1164.all;&lt;br /&gt;
library work;&lt;br /&gt;
use work.all;&lt;br /&gt;
&lt;br /&gt;
entity alu_tb is&lt;br /&gt;
end entity alu_tb;&lt;br /&gt;
&lt;br /&gt;
architecture struct of alu_tb is&lt;br /&gt;
  --Deklaring av signal som skal koblast til komponentane.&lt;br /&gt;
  --Alle innsignal er felles, medan vi har 2 forskjellige utsignal.&lt;br /&gt;
  signal clk           : std_logic;&lt;br /&gt;
  signal reset         : std_logic;&lt;br /&gt;
  signal enable_in     : std_logic;&lt;br /&gt;
  signal start         : std_logic;&lt;br /&gt;
  signal enable        : std_logic;&lt;br /&gt;
  signal do_add        : std_logic;&lt;br /&gt;
  signal do_subtract   : std_logic;&lt;br /&gt;
  signal do_hold       : std_logic;&lt;br /&gt;
  signal data_in       : std_logic_vector(3 downto 0);&lt;br /&gt;
  signal data_out      : std_logic_vector(3 downto 0);&lt;br /&gt;
  signal data_out_synt : std_logic_vector(3 downto 0);&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
  --Deklarer komponenten alu.&lt;br /&gt;
  alu : entity add_sub_alu(algorithm)&lt;br /&gt;
    --Kobler signala til den opprinnelige komponenten.&lt;br /&gt;
    port map (&lt;br /&gt;
    clk =&amp;gt; clk,&lt;br /&gt;
    rst =&amp;gt; reset,&lt;br /&gt;
    enable_in =&amp;gt; enable_in,&lt;br /&gt;
    start =&amp;gt; start,&lt;br /&gt;
    enable =&amp;gt; enable,&lt;br /&gt;
    do_add =&amp;gt; do_add,&lt;br /&gt;
    do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
    do_hold =&amp;gt; do_hold,&lt;br /&gt;
    data_in =&amp;gt; data_in,&lt;br /&gt;
    data_out =&amp;gt; data_out);&lt;br /&gt;
&lt;br /&gt;
  --Deklarer komponenten alu_synt.&lt;br /&gt;
  alu_synt : entity add_sub_alu_synth(structure)&lt;br /&gt;
  --Kobler signala til den synthiserte komponenten.&lt;br /&gt;
    port map (&lt;br /&gt;
    clk =&amp;gt; clk,&lt;br /&gt;
    rst =&amp;gt; reset,&lt;br /&gt;
    enable_in =&amp;gt; enable_in,&lt;br /&gt;
    start =&amp;gt; start,&lt;br /&gt;
    enable =&amp;gt; enable,&lt;br /&gt;
    do_add =&amp;gt; do_add,&lt;br /&gt;
    do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
    do_hold =&amp;gt; do_hold,&lt;br /&gt;
    data_in =&amp;gt; data_in,&lt;br /&gt;
    data_out =&amp;gt; data_out_synt);&lt;br /&gt;
&lt;br /&gt;
  --Klokkegenerator&lt;br /&gt;
  clock_gen : process&lt;br /&gt;
    begin&lt;br /&gt;
    clk &amp;lt;= &#039;0&#039;, &#039;1&#039; after 50 ns;&lt;br /&gt;
    wait for 100 ns;&lt;br /&gt;
  end process clock_gen;&lt;br /&gt;
&lt;br /&gt;
  --Setter testvektorane.&lt;br /&gt;
  reset &amp;lt;= &#039;0&#039;, &#039;1&#039; after 60 ns;&lt;br /&gt;
  enable &amp;lt;= &#039;1&#039;, &#039;0&#039; after 900 ns;&lt;br /&gt;
  enable_in &amp;lt;= &#039;1&#039;, &#039;0&#039; after 400 ns;&lt;br /&gt;
  start &amp;lt;= &#039;1&#039;, &#039;0&#039; after 300 ns;&lt;br /&gt;
  do_add &amp;lt;= &#039;1&#039;, &#039;0&#039; after 660 ns;&lt;br /&gt;
  do_subtract &amp;lt;= &#039;0&#039;;&lt;br /&gt;
  do_hold &amp;lt;= &#039;0&#039;;&lt;br /&gt;
  data_in &amp;lt;= X&amp;quot;3&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  --Test process for å samanlikne utsignala kvart nanosekund.&lt;br /&gt;
  test : process&lt;br /&gt;
  begin&lt;br /&gt;
  wait for 1 ns;&lt;br /&gt;
  assert (data_out = data_out_synt)&lt;br /&gt;
  report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
  severity Error;&lt;br /&gt;
  end process test;&lt;br /&gt;
&lt;br /&gt;
end architecture struct;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2817</id>
		<title>Synthese av VHDL</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2817"/>
		<updated>2021-02-05T08:05:35Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: /* Precision */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Syntetiseringen av VHDL kode===&lt;br /&gt;
&lt;br /&gt;
Grunnen til at vi skal syntetisere koden, er at vi må lage beskrivelse av koden tilpassa ein krets.&lt;br /&gt;
&lt;br /&gt;
Vi vil no prøve å synthesisere vhdl kode. Og etterpå vil vi lage ein testbenk der vi samanliknar utsignala frå den syntetiserte og den opprinnelige koden. Vi bruker ein alu som eksempel.&lt;br /&gt;
&lt;br /&gt;
==Precision==&lt;br /&gt;
&lt;br /&gt;
Precision bruker Vivado til å syntetisere vhdl-koden. For å starte synteseprogrammet:&lt;br /&gt;
&lt;br /&gt;
 export LM_LICENSE_FILE=1717@lisensserver:2100@lisensserver&lt;br /&gt;
 source /eda/mentor/2019-20/scripts/PRECISION_2019.1.1_RHELx86.sh&lt;br /&gt;
 precision&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Vel deretter New Project, og deretter Add input file (i dette tilfelle add_sub_alu.vhd).&lt;br /&gt;
Så går vi inn på Setup design, velger ein kretsprodusent, den ønska kretsen og designfrekvens, for eksempel Zynq med frekvens 200MHz. For å få ut en vhdl fil av den syntetiserte koden må en gå på Tools-&amp;gt;Options-&amp;gt;Output og hak av for VHDL og trykk ok.&lt;br /&gt;
&lt;br /&gt;
Pass på at Precision finner Vivado, settes i menyen:&lt;br /&gt;
 Tools &amp;gt; Options &amp;gt; Place and Route Settings&lt;br /&gt;
deretter&lt;br /&gt;
 Vivado &amp;gt; Integrated Place and Route &amp;gt; path to Xilinx Vivado installation tree&lt;br /&gt;
settes til&lt;br /&gt;
 /eda/xilinx/Vivado/2020.2&lt;br /&gt;
&lt;br /&gt;
Trykk så compile, og synthesize. &lt;br /&gt;
No kan vi sjå på den generte kretsen i RTL Schematic og Technology Schematic (syntese med den valgte kretsen) under Schematics på venstre side.&lt;br /&gt;
&lt;br /&gt;
==Questasim==&lt;br /&gt;
&lt;br /&gt;
Start opp Questasim, lag nytt prosjekt og legg til vhdl fila (add_sub_alu.vhdl). Så legg vi til fila som Precision generte i prosjektdir til &#039;precision/prosjektnavn_temp_1/prosjektnavn.vhd&#039; (i vårt tilfelle &#039;alu/add_sub_alu_temp_1/add_sub_alu.vhd&#039;).&lt;br /&gt;
&lt;br /&gt;
Vi trenger simuleringsbibliotek for den valgte kretsfamilien for å kunne simulere etter &amp;quot;Place and Route&amp;quot;. Disse bibliotekene kan genereres fra Vivado med menyen&lt;br /&gt;
 Tools &amp;gt; Compile Simulation Libraries&lt;br /&gt;
men, vi har kompilert disse unisim-bibliotekene til mappen /eda/xilinx/lib. Du kan &amp;quot;mappe&amp;quot; disse slik:&lt;br /&gt;
&lt;br /&gt;
 vmap unisim /eda/xilinx/lib/unisim&lt;br /&gt;
 &lt;br /&gt;
Deretter legger vi til ei ny vhdl fil der vi skal lage testbenken vår. Vi legger til ein komponent av den opprinnelige og den synthesiserte vhdl koden. Vi koblar alle inngangane til samme signal på testbenken, og gir ut 2 forskjellige utsignal for å samanlikne ved hjelp av assert(sjå fila alu_tb.vhdl). På grunn av at utsignala av dei to komponentane ikkje skifta heilt synkront, testa vi berre kvart nanosekund ved å putta assert inn i ein process med wait for 1ns:&lt;br /&gt;
&lt;br /&gt;
 test : process&lt;br /&gt;
 begin&lt;br /&gt;
 wait for 1 ns;&lt;br /&gt;
 assert (data_out = data_out_synt)&lt;br /&gt;
 report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
 severity Error;&lt;br /&gt;
 end process test;&lt;br /&gt;
&lt;br /&gt;
Når vi har laga testbenken, kompilerer vi filene (husk å kompilere i rett rekkefølge med compileorder-&amp;gt;autogenerate første gong).&lt;br /&gt;
&lt;br /&gt;
Siden precision generer samme navn på entityen og architecturen på den syntetiserte filen som i den orginale så vil ikke simulatoren kjøre de samtidig. Dette endres ved å endre entity fra add_sub_alu til add_sub_alu_synth og skifte navnet på architecture fra algoritm til structure øverst og nederst i den syntetiserte filen.&lt;br /&gt;
&lt;br /&gt;
==Simulering med timing==&lt;br /&gt;
&lt;br /&gt;
Eksempel på start av simulering med timing:&lt;br /&gt;
&lt;br /&gt;
 vsim -t ps alu_tb -sdfmax :alu_tb:ali=/heim/yngve/vhdl/syntese/alu_temp_1/simulation/modelsim/add_sub_alu_vhd.sdo&lt;br /&gt;
&lt;br /&gt;
Vi kan sjå at i dei første 50 nanosekunda er utsignala ulike. Dette er fordi før første klokkeflanke er verdiane udefinert i den opprinnelige komponenten, medan den synthesisere ikkje kan ha udefinerte verdiar. I Questasim vil vi derfor få ein del feilmeldingar dei første 50 nanosekunda.&lt;br /&gt;
&lt;br /&gt;
==Konklusjon==&lt;br /&gt;
&lt;br /&gt;
Vi kan teste om den syntesiserte komponenten oppfører seg likt med den opprinnelige komponenten ved å koble begge to til samme testbenk. Vi fekk problem i overgangane når vi testa kontinuerlig, så vi løyste problemet ved å berre teste kvart naonosekund. Bortsett frå dei første 50 nanosekunda (sjå grunn over) kan vi sjå at begge komponetane gir ut samme utsignal. Vi prøvde å bruke samme enitynavn på begge komponentane med ulik arcitechture, men fekk berre lov å kompilere og ikkje simulere. Vi kan derfor konkludere med at desse må ha ulike navn.&lt;br /&gt;
&lt;br /&gt;
==Kode==&lt;br /&gt;
&lt;br /&gt;
===Kode til add_sub_alu.vhd===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.All;&lt;br /&gt;
USE ieee.std_logic_unsigned.all;&lt;br /&gt;
&lt;br /&gt;
ENTITY add_sub_alu IS&lt;br /&gt;
PORT (&lt;br /&gt;
  clk         : IN  std_logic;&lt;br /&gt;
  rst         : IN  std_logic;&lt;br /&gt;
  enable_in   : IN  std_logic;&lt;br /&gt;
  start       : IN  std_logic;&lt;br /&gt;
  enable      : IN  std_logic;&lt;br /&gt;
  do_add      : IN  std_logic;&lt;br /&gt;
  do_subtract : IN  std_logic;&lt;br /&gt;
  do_hold     : IN  std_logic;&lt;br /&gt;
  data_in     : IN  std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  data_out    : OUT std_logic_vector(3 DOWNTO 0) BUS);&lt;br /&gt;
END add_sub_alu;&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE algorithm OF add_sub_alu IS&lt;br /&gt;
  TYPE   states          IS (hold, reset, add, subtract);&lt;br /&gt;
  SIGNAL state_var       : states;&lt;br /&gt;
  SIGNAL reg, int_reg    : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  SIGNAL latched_data_in : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
BEGIN&lt;br /&gt;
&lt;br /&gt;
latch: PROCESS (enable_in, data_in)is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (enable_in = &#039;1&#039;) THEN&lt;br /&gt;
    latched_data_in &amp;lt;= data_in;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS latch;&lt;br /&gt;
&lt;br /&gt;
fsm: PROCESS (clk, rst) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (rst = &#039;0&#039;) THEN&lt;br /&gt;
    state_var &amp;lt;= reset;&lt;br /&gt;
  ELSIF rising_edge(clk) THEN&lt;br /&gt;
    CASE state_var IS&lt;br /&gt;
      WHEN hold =&amp;gt;&lt;br /&gt;
        IF (start = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= reset;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN reset    =&amp;gt;&lt;br /&gt;
        IF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN add      =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN subtract =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN OTHERS =&amp;gt; state_var &amp;lt;= reset;&lt;br /&gt;
    END CASE;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS fsm;&lt;br /&gt;
&lt;br /&gt;
alu: PROCESS (state_var, latched_data_in, reg)is&lt;br /&gt;
BEGIN&lt;br /&gt;
CASE state_var IS&lt;br /&gt;
  WHEN add      =&amp;gt; int_reg &amp;lt;= reg + latched_data_in;&lt;br /&gt;
  WHEN subtract =&amp;gt; int_reg &amp;lt;= reg - latched_data_in;&lt;br /&gt;
  WHEN reset    =&amp;gt; int_reg &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
  WHEN hold     =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
  WHEN OTHERS   =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
END CASE;&lt;br /&gt;
END PROCESS alu;&lt;br /&gt;
&lt;br /&gt;
mem: PROCESS (clk) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF rising_edge(clk) THEN&lt;br /&gt;
    reg &amp;lt;= int_reg;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS mem;&lt;br /&gt;
&lt;br /&gt;
tri: PROCESS (enable, reg) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  FOR i IN 3 DOWNTO 0 LOOP&lt;br /&gt;
    IF (enable = &#039;1&#039;) THEN&lt;br /&gt;
      data_out(i) &amp;lt;= reg(i);&lt;br /&gt;
    ELSE&lt;br /&gt;
      data_out(i) &amp;lt;= &#039;Z&#039;;&lt;br /&gt;
    END IF;&lt;br /&gt;
  END LOOP;&lt;br /&gt;
END PROCESS tri;&lt;br /&gt;
&lt;br /&gt;
END algorithm;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Koden til alu_tb.vhdl===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library ieee;&lt;br /&gt;
use ieee.std_logic_1164.all;&lt;br /&gt;
library work;&lt;br /&gt;
use work.all;&lt;br /&gt;
&lt;br /&gt;
entity alu_tb is&lt;br /&gt;
end entity alu_tb;&lt;br /&gt;
&lt;br /&gt;
architecture struct of alu_tb is&lt;br /&gt;
--Deklaring av signal som skal koblast til komponentane.&lt;br /&gt;
--Alle innsignal er felles, medan vi har 2 forskjellige utsignal.&lt;br /&gt;
signal clk, reset : std_logic;&lt;br /&gt;
signal enable_in : std_logic;&lt;br /&gt;
signal start : std_logic;&lt;br /&gt;
signal enable : std_logic;&lt;br /&gt;
signal do_add : std_logic;&lt;br /&gt;
signal do_subtract : std_logic;&lt;br /&gt;
signal do_hold : std_logic;&lt;br /&gt;
signal data_in : std_logic_vector(3 downto 0);&lt;br /&gt;
signal data_out : std_logic_vector(3 downto 0);&lt;br /&gt;
signal data_out_synt : std_logic_vector(3 downto 0);&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
--Deklarer komponenten alu.&lt;br /&gt;
alu : entity add_sub_alu(algorithm)&lt;br /&gt;
&lt;br /&gt;
--Kobler signala til den opprinnelige komponenten.&lt;br /&gt;
port map (&lt;br /&gt;
clk =&amp;gt; clk,&lt;br /&gt;
rst =&amp;gt; reset,&lt;br /&gt;
enable_in =&amp;gt; enable_in,&lt;br /&gt;
start =&amp;gt; start,&lt;br /&gt;
enable =&amp;gt; enable,&lt;br /&gt;
do_add =&amp;gt; do_add,&lt;br /&gt;
do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
do_hold =&amp;gt; do_hold,&lt;br /&gt;
data_in =&amp;gt; data_in,&lt;br /&gt;
data_out =&amp;gt; data_out);&lt;br /&gt;
&lt;br /&gt;
--Deklarer komponenten alu_synt.&lt;br /&gt;
alu_synt : entity add_sub_alu_synth(structure)&lt;br /&gt;
&lt;br /&gt;
--Kobler signala til den synthiserte komponenten.&lt;br /&gt;
port map (&lt;br /&gt;
clk =&amp;gt; clk,&lt;br /&gt;
rst =&amp;gt; reset,&lt;br /&gt;
enable_in =&amp;gt; enable_in,&lt;br /&gt;
start =&amp;gt; start,&lt;br /&gt;
enable =&amp;gt; enable,&lt;br /&gt;
do_add =&amp;gt; do_add,&lt;br /&gt;
do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
do_hold =&amp;gt; do_hold,&lt;br /&gt;
data_in =&amp;gt; data_in,&lt;br /&gt;
data_out =&amp;gt; data_out_synt);&lt;br /&gt;
&lt;br /&gt;
--Klokkegenerator&lt;br /&gt;
clock_gen : process&lt;br /&gt;
begin&lt;br /&gt;
clk &amp;lt;= &#039;0&#039;, &#039;1&#039; after 50 ns;&lt;br /&gt;
wait for 100 ns;&lt;br /&gt;
end process clock_gen;&lt;br /&gt;
&lt;br /&gt;
--Setter testvektorane.&lt;br /&gt;
reset &amp;lt;= &#039;0&#039;, &#039;1&#039; after 60 ns;&lt;br /&gt;
enable &amp;lt;= &#039;1&#039;, &#039;0&#039; after 900 ns;&lt;br /&gt;
enable_in &amp;lt;= &#039;1&#039;, &#039;0&#039; after 400 ns;&lt;br /&gt;
start &amp;lt;= &#039;1&#039;, &#039;0&#039; after 300 ns;&lt;br /&gt;
do_add &amp;lt;= &#039;1&#039;, &#039;0&#039; after 660 ns;&lt;br /&gt;
do_subtract &amp;lt;= &#039;0&#039;;&lt;br /&gt;
do_hold &amp;lt;= &#039;0&#039;;&lt;br /&gt;
data_in &amp;lt;= X&amp;quot;3&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
--Test process for å samanlikne utsignala kvart nanosekund.&lt;br /&gt;
test : process&lt;br /&gt;
begin&lt;br /&gt;
wait for 1 ns;&lt;br /&gt;
assert (data_out = data_out_synt)&lt;br /&gt;
report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
severity Error;&lt;br /&gt;
end process test;&lt;br /&gt;
&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Modelsim/Questa&amp;diff=2816</id>
		<title>Modelsim/Questa</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Modelsim/Questa&amp;diff=2816"/>
		<updated>2021-02-04T21:13:27Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: /* Referanselitteratur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Simulering av VHDL]]&lt;br /&gt;
&lt;br /&gt;
[[VHDL Testbenk]]&lt;br /&gt;
&lt;br /&gt;
[[Synthese av VHDL]]&lt;br /&gt;
&lt;br /&gt;
== Referanselitteratur ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/VHDL Wikipedia:VHDL]&lt;br /&gt;
&lt;br /&gt;
[http://freerangefactory.org/books_tuts.html Free Range VHDL textbook]&lt;br /&gt;
&lt;br /&gt;
[http://esd.cs.ucr.edu/labs/tutorial/ VHDL Tutorial: Learn by Example]&lt;br /&gt;
&lt;br /&gt;
[http://www.ioenotes.edu.np/media/notes/embedded-system/vhdl.pdf VHDL Quick Start (slides by Ashenden)]&lt;br /&gt;
&lt;br /&gt;
[http://model.com/content/modelsim-pe-simulation-and-debug Modelsim]&lt;br /&gt;
&lt;br /&gt;
[http://m.eet.com/media/1151614/23798-46098.pdf 10 tips for generating reusable VHDL]&lt;br /&gt;
&lt;br /&gt;
[http://www.actel.com/documents/hdlcode_ug.pdf Actel HDL coding Style Guide]&lt;br /&gt;
&lt;br /&gt;
[http://www.seas.upenn.edu/~ese171/vhdl/vhdl_primer.html VHDL primer]&lt;br /&gt;
&lt;br /&gt;
[https://bitvis.no/dev-tools/uvvm/ Bitvis Universal VHDL Verification Methodology ]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/UVVM Bitvis UVVM på GitHub ]&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=VHDL_Testbenk&amp;diff=2815</id>
		<title>VHDL Testbenk</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=VHDL_Testbenk&amp;diff=2815"/>
		<updated>2021-02-04T21:09:23Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: /* Do-file og testbenk */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Simulering av kode og testbenk i QuestaSim===&lt;br /&gt;
&lt;br /&gt;
==Do-file og testbenk==&lt;br /&gt;
&lt;br /&gt;
Vi vil lage ei Do-file for å sleppe å skrive inn stimuli manuellt kvar gang vi simulerer. &lt;br /&gt;
&lt;br /&gt;
Testbenken er eit nyttig hjelpemiddel for å kontrollere resultet frå simulering.&lt;br /&gt;
&lt;br /&gt;
Oppstart av modelsim&lt;br /&gt;
&lt;br /&gt;
Opne eit terminalvindu, og skriv : &lt;br /&gt;
&lt;br /&gt;
 ssh -X mikroserver4&lt;br /&gt;
 source /eda/mentor/2019-20/scripts/QUESTA-CORE-PRIME_2019.4_RHELx86.sh&lt;br /&gt;
 vsim&lt;br /&gt;
&lt;br /&gt;
==Lage prosjekt i modelsim==&lt;br /&gt;
&lt;br /&gt;
Velg:  file &amp;gt;new&amp;gt;project. Deretter kan du legge til vhdl-filer ved å velge add to project&amp;gt;add existing file. I denne oppgåva treng vi fila: sr_latch. Husk å kompliere vhdl filer før du simulerer.&lt;br /&gt;
&lt;br /&gt;
Koden til SR_latch.vhdl&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.ALL;&lt;br /&gt;
&lt;br /&gt;
ENTITY SR_latch IS&lt;br /&gt;
  PORT (&lt;br /&gt;
        S,R  : IN std_logic ;&lt;br /&gt;
        Q,QB : INOUT std_logic );&lt;br /&gt;
END SR_latch;&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE behave OF SR_latch IS&lt;br /&gt;
&lt;br /&gt;
BEGIN &lt;br /&gt;
--  behave &lt;br /&gt;
   Q &amp;lt;= S nand QB;&lt;br /&gt;
   QB &amp;lt;= R nand Q;  &lt;br /&gt;
END behave;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Bruk av &amp;quot;Do-file&amp;quot;==&lt;br /&gt;
&lt;br /&gt;
Første del av oppgåva er å konstruere ei såkalt do-file som beskriv stimuli til sr_latch. Dette er ganske enkelt ei textfil som kan sjå slik ut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Starter simulering på nytt (clear)&lt;br /&gt;
restart -f&lt;br /&gt;
&lt;br /&gt;
# Force s til 1 etter 100ns og til 0 etter 200ns, gjentar etter 200 ns&lt;br /&gt;
force s 1 100 ns, 0 200 ns -repeat 200 ns&lt;br /&gt;
force r 1 100 ns, 0 300 ns -repeat 400 ns&lt;br /&gt;
&lt;br /&gt;
# Simulerer i 800ns&lt;br /&gt;
run 800 ns&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bruk av do-file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vsim -voptargs=+acc SR_latch&lt;br /&gt;
add wave *&lt;br /&gt;
do f.do&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Resultat av simulering&lt;br /&gt;
&lt;br /&gt;
 # ** Error: (vsim-3601) Iteration limit reached at time 500 ns.&lt;br /&gt;
Som viser at vi får oscillasjon etter 500ns.&lt;br /&gt;
&lt;br /&gt;
Vi får også opp eit wave-vindu med alle signal som er beskrive i entity.&lt;br /&gt;
&lt;br /&gt;
==Testbenk i VHDL==&lt;br /&gt;
&lt;br /&gt;
No skal vi lære oss å lage ein testbench som testar utverdiane mot forventa resultat og skriv ut forskjellige feilmeldingar.&lt;br /&gt;
Velg: add to project&amp;gt;new file (type vhdl). I denne skriv vi så testbenken vår. &lt;br /&gt;
&lt;br /&gt;
*Eksempelkode til SR_tb.vhdl:*&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library ieee;&lt;br /&gt;
use ieee.std_logic_1164.all;&lt;br /&gt;
library work;&lt;br /&gt;
use work.all;&lt;br /&gt;
&lt;br /&gt;
--Navn på testbenken. Vi treng ingen kopling til utanverda i testbenken.&lt;br /&gt;
entity sr_tb is&lt;br /&gt;
end entity sr_tb;&lt;br /&gt;
&lt;br /&gt;
architecture struct of sr_tb is&lt;br /&gt;
--Deklarerer testsignalar og kva type dei er.&lt;br /&gt;
signal S_tb : std_logic;&lt;br /&gt;
signal R_tb : std_logic;&lt;br /&gt;
signal Q_tb : std_logic;&lt;br /&gt;
signal QB_tb : std_logic;&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
--Velg kva einheit testbenken skal teste.&lt;br /&gt;
SR : entity SR_latch(behave)&lt;br /&gt;
&lt;br /&gt;
--Koblar signala fra einheiten til testbenken.&lt;br /&gt;
port map (&lt;br /&gt;
S =&amp;gt; S_tb,&lt;br /&gt;
R =&amp;gt; R_tb,&lt;br /&gt;
Q =&amp;gt; Q_tb,&lt;br /&gt;
QB =&amp;gt; QB_tb);&lt;br /&gt;
&lt;br /&gt;
--Setter testvektorane, venter og ser kva vi får ut. &lt;br /&gt;
--Samanliknar med forventa resultat, og gir ut eventuelle error.&lt;br /&gt;
--Vi har lagt inn alle feiltypane i assert som eit eksempel.&lt;br /&gt;
process&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
--Setter&lt;br /&gt;
S_tb &amp;lt;= &#039;0&#039;;&lt;br /&gt;
R_tb &amp;lt;= &#039;1&#039;;&lt;br /&gt;
&lt;br /&gt;
wait for 100 ns;&lt;br /&gt;
&lt;br /&gt;
assert (Q_tb = &#039;1&#039;)&lt;br /&gt;
	report &amp;quot;Q vart ikkje 1!&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
&lt;br /&gt;
assert (QB_tb = &#039;0&#039;)&lt;br /&gt;
	report &amp;quot;QB vart ikkje 0!&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
	&lt;br /&gt;
--Ingen endring&lt;br /&gt;
S_tb &amp;lt;= &#039;1&#039;;&lt;br /&gt;
R_tb &amp;lt;= &#039;1&#039;;&lt;br /&gt;
wait for 100 ns;&lt;br /&gt;
&lt;br /&gt;
--Tester på feil verdier for å lage feilmelding&lt;br /&gt;
assert (Q_tb = &#039;0&#039;)&lt;br /&gt;
	report &amp;quot;Dette er ein feil&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
&lt;br /&gt;
assert (QB_tb = &#039;1&#039;)&lt;br /&gt;
	report &amp;quot;Ein feil til&amp;quot;&lt;br /&gt;
	severity warning;&lt;br /&gt;
&lt;br /&gt;
--Reset	&lt;br /&gt;
S_tb &amp;lt;= &#039;1&#039;;&lt;br /&gt;
R_tb &amp;lt;= &#039;0&#039;;&lt;br /&gt;
&lt;br /&gt;
wait for 100 ns;&lt;br /&gt;
&lt;br /&gt;
assert (Q_tb = &#039;0&#039;)&lt;br /&gt;
	report &amp;quot;Q vart ikkje 0!&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
&lt;br /&gt;
assert (QB_tb = &#039;1&#039;)&lt;br /&gt;
	report &amp;quot;QB vart ikkje 1!&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
&lt;br /&gt;
--Ingen endring&lt;br /&gt;
S_tb &amp;lt;= &#039;1&#039;;&lt;br /&gt;
R_tb &amp;lt;= &#039;1&#039;;&lt;br /&gt;
wait for 100 ns;&lt;br /&gt;
&lt;br /&gt;
--Tester på feil verdier&lt;br /&gt;
assert (Q_tb = &#039;1&#039;)&lt;br /&gt;
	report &amp;quot;Endå meir feil&amp;quot;&lt;br /&gt;
	severity note;&lt;br /&gt;
&lt;br /&gt;
assert (QB_tb = &#039;0&#039;)&lt;br /&gt;
	report &amp;quot;hu, masse feil ja&amp;quot;&lt;br /&gt;
	severity Warning;&lt;br /&gt;
&lt;br /&gt;
--Reset&lt;br /&gt;
S_tb &amp;lt;= &#039;1&#039;;&lt;br /&gt;
R_tb &amp;lt;= &#039;0&#039;;&lt;br /&gt;
wait for 100 ns;&lt;br /&gt;
&lt;br /&gt;
assert (Q_tb = &#039;0&#039;)&lt;br /&gt;
	report &amp;quot;Q does not match the expected value!&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
&lt;br /&gt;
assert (QB_tb = &#039;1&#039;)&lt;br /&gt;
	report &amp;quot;QB does not match the expected value!&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
&lt;br /&gt;
--Set og reset&lt;br /&gt;
S_tb &amp;lt;= &#039;0&#039;;&lt;br /&gt;
R_tb &amp;lt;= &#039;0&#039;;&lt;br /&gt;
wait for 100 ns;&lt;br /&gt;
&lt;br /&gt;
assert (Q_tb = &#039;1&#039;)&lt;br /&gt;
	report &amp;quot;Q does not match the expected value!&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
&lt;br /&gt;
assert (QB_tb = &#039;1&#039;)&lt;br /&gt;
	report &amp;quot;QB does not match the expected value!&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
&lt;br /&gt;
--Oscillilerer&lt;br /&gt;
S_tb &amp;lt;= &#039;1&#039;;&lt;br /&gt;
R_tb &amp;lt;= &#039;1&#039;;&lt;br /&gt;
wait for 100 ns;&lt;br /&gt;
&lt;br /&gt;
assert (Q_tb = &#039;1&#039;)&lt;br /&gt;
	report &amp;quot;Q does not match the expected value!&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
&lt;br /&gt;
assert (QB_tb = &#039;0&#039;)&lt;br /&gt;
	report &amp;quot;QB does not match the expected value!&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
&lt;br /&gt;
end process;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For å kjøre igjennom hele filen bruker en&lt;br /&gt;
 run -all&lt;br /&gt;
&lt;br /&gt;
==Resultat==&lt;br /&gt;
Vi kan leggje inn feil for å få fram nokon feil for å vise forskjellige  feilmeldinger. Vi fekk også SR_latch til å oscillere.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# ** Error: Dette er ein feil&lt;br /&gt;
#    Time: 200 ns  Iteration: 0  Instance: :sr_tb&lt;br /&gt;
# ** Warning: Ein feil til&lt;br /&gt;
#    Time: 200 ns  Iteration: 0  Instance: :sr_tb&lt;br /&gt;
# ** Note: Endå meir feil&lt;br /&gt;
#    Time: 400 ns  Iteration: 0  Instance: :sr_tb&lt;br /&gt;
# ** Warning: hu, masse feil ja&lt;br /&gt;
#    Time: 400 ns  Iteration: 0  Instance: :sr_tb&lt;br /&gt;
# ** Error: (vsim-3601) Iteration limit reached at time 600 ns.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Om en legger til testbenk signalene i wave vinduet så får en opp markeringer der hvor det har oppstått feil, rød for error og gul for warning. En kan så trykke på markeringene og få opp feilmeldingen.&lt;br /&gt;
&lt;br /&gt;
==Konklusjon==&lt;br /&gt;
&lt;br /&gt;
Vi kan lage ein do-file som styrer stimuli under simulering, slik at vi slepp å skrive kommandoer kvar gang vi simulerer. Vi kan lage ein testbench for å simuler og kontrollere svaret mot forventa resultat. Med assert kan vi skrive ut feilmeldinger av ulike typer når det oppstår feil.&lt;br /&gt;
&lt;br /&gt;
[[Category:VHDL]] [[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=VHDL_Testbenk&amp;diff=2814</id>
		<title>VHDL Testbenk</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=VHDL_Testbenk&amp;diff=2814"/>
		<updated>2021-02-04T21:08:46Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Simulering av kode og testbenk i QuestaSim===&lt;br /&gt;
&lt;br /&gt;
==Do-file og testbenk==&lt;br /&gt;
&lt;br /&gt;
Vi vil lage ei Do-file for å sleppe å skrive inn stimuli manuellt kvar gang vi simulerer. &lt;br /&gt;
&lt;br /&gt;
Testbenken er eit nyttig hjelpemiddel for å kontrollere resultet frå simulering.&lt;br /&gt;
&lt;br /&gt;
Oppstart av modelsim&lt;br /&gt;
&lt;br /&gt;
Opne eit terminalvindu, og skriv : &lt;br /&gt;
&lt;br /&gt;
 ssh -X mikroserver4&lt;br /&gt;
 source /eda/mentor/2019-20/scripts/QUESTA-CORE-PRIME_2019.4_RHELx86.shvsim&lt;br /&gt;
&lt;br /&gt;
==Lage prosjekt i modelsim==&lt;br /&gt;
&lt;br /&gt;
Velg:  file &amp;gt;new&amp;gt;project. Deretter kan du legge til vhdl-filer ved å velge add to project&amp;gt;add existing file. I denne oppgåva treng vi fila: sr_latch. Husk å kompliere vhdl filer før du simulerer.&lt;br /&gt;
&lt;br /&gt;
Koden til SR_latch.vhdl&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.ALL;&lt;br /&gt;
&lt;br /&gt;
ENTITY SR_latch IS&lt;br /&gt;
  PORT (&lt;br /&gt;
        S,R  : IN std_logic ;&lt;br /&gt;
        Q,QB : INOUT std_logic );&lt;br /&gt;
END SR_latch;&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE behave OF SR_latch IS&lt;br /&gt;
&lt;br /&gt;
BEGIN &lt;br /&gt;
--  behave &lt;br /&gt;
   Q &amp;lt;= S nand QB;&lt;br /&gt;
   QB &amp;lt;= R nand Q;  &lt;br /&gt;
END behave;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Bruk av &amp;quot;Do-file&amp;quot;==&lt;br /&gt;
&lt;br /&gt;
Første del av oppgåva er å konstruere ei såkalt do-file som beskriv stimuli til sr_latch. Dette er ganske enkelt ei textfil som kan sjå slik ut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Starter simulering på nytt (clear)&lt;br /&gt;
restart -f&lt;br /&gt;
&lt;br /&gt;
# Force s til 1 etter 100ns og til 0 etter 200ns, gjentar etter 200 ns&lt;br /&gt;
force s 1 100 ns, 0 200 ns -repeat 200 ns&lt;br /&gt;
force r 1 100 ns, 0 300 ns -repeat 400 ns&lt;br /&gt;
&lt;br /&gt;
# Simulerer i 800ns&lt;br /&gt;
run 800 ns&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bruk av do-file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vsim -voptargs=+acc SR_latch&lt;br /&gt;
add wave *&lt;br /&gt;
do f.do&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Resultat av simulering&lt;br /&gt;
&lt;br /&gt;
 # ** Error: (vsim-3601) Iteration limit reached at time 500 ns.&lt;br /&gt;
Som viser at vi får oscillasjon etter 500ns.&lt;br /&gt;
&lt;br /&gt;
Vi får også opp eit wave-vindu med alle signal som er beskrive i entity.&lt;br /&gt;
&lt;br /&gt;
==Testbenk i VHDL==&lt;br /&gt;
&lt;br /&gt;
No skal vi lære oss å lage ein testbench som testar utverdiane mot forventa resultat og skriv ut forskjellige feilmeldingar.&lt;br /&gt;
Velg: add to project&amp;gt;new file (type vhdl). I denne skriv vi så testbenken vår. &lt;br /&gt;
&lt;br /&gt;
*Eksempelkode til SR_tb.vhdl:*&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library ieee;&lt;br /&gt;
use ieee.std_logic_1164.all;&lt;br /&gt;
library work;&lt;br /&gt;
use work.all;&lt;br /&gt;
&lt;br /&gt;
--Navn på testbenken. Vi treng ingen kopling til utanverda i testbenken.&lt;br /&gt;
entity sr_tb is&lt;br /&gt;
end entity sr_tb;&lt;br /&gt;
&lt;br /&gt;
architecture struct of sr_tb is&lt;br /&gt;
--Deklarerer testsignalar og kva type dei er.&lt;br /&gt;
signal S_tb : std_logic;&lt;br /&gt;
signal R_tb : std_logic;&lt;br /&gt;
signal Q_tb : std_logic;&lt;br /&gt;
signal QB_tb : std_logic;&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
--Velg kva einheit testbenken skal teste.&lt;br /&gt;
SR : entity SR_latch(behave)&lt;br /&gt;
&lt;br /&gt;
--Koblar signala fra einheiten til testbenken.&lt;br /&gt;
port map (&lt;br /&gt;
S =&amp;gt; S_tb,&lt;br /&gt;
R =&amp;gt; R_tb,&lt;br /&gt;
Q =&amp;gt; Q_tb,&lt;br /&gt;
QB =&amp;gt; QB_tb);&lt;br /&gt;
&lt;br /&gt;
--Setter testvektorane, venter og ser kva vi får ut. &lt;br /&gt;
--Samanliknar med forventa resultat, og gir ut eventuelle error.&lt;br /&gt;
--Vi har lagt inn alle feiltypane i assert som eit eksempel.&lt;br /&gt;
process&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
--Setter&lt;br /&gt;
S_tb &amp;lt;= &#039;0&#039;;&lt;br /&gt;
R_tb &amp;lt;= &#039;1&#039;;&lt;br /&gt;
&lt;br /&gt;
wait for 100 ns;&lt;br /&gt;
&lt;br /&gt;
assert (Q_tb = &#039;1&#039;)&lt;br /&gt;
	report &amp;quot;Q vart ikkje 1!&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
&lt;br /&gt;
assert (QB_tb = &#039;0&#039;)&lt;br /&gt;
	report &amp;quot;QB vart ikkje 0!&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
	&lt;br /&gt;
--Ingen endring&lt;br /&gt;
S_tb &amp;lt;= &#039;1&#039;;&lt;br /&gt;
R_tb &amp;lt;= &#039;1&#039;;&lt;br /&gt;
wait for 100 ns;&lt;br /&gt;
&lt;br /&gt;
--Tester på feil verdier for å lage feilmelding&lt;br /&gt;
assert (Q_tb = &#039;0&#039;)&lt;br /&gt;
	report &amp;quot;Dette er ein feil&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
&lt;br /&gt;
assert (QB_tb = &#039;1&#039;)&lt;br /&gt;
	report &amp;quot;Ein feil til&amp;quot;&lt;br /&gt;
	severity warning;&lt;br /&gt;
&lt;br /&gt;
--Reset	&lt;br /&gt;
S_tb &amp;lt;= &#039;1&#039;;&lt;br /&gt;
R_tb &amp;lt;= &#039;0&#039;;&lt;br /&gt;
&lt;br /&gt;
wait for 100 ns;&lt;br /&gt;
&lt;br /&gt;
assert (Q_tb = &#039;0&#039;)&lt;br /&gt;
	report &amp;quot;Q vart ikkje 0!&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
&lt;br /&gt;
assert (QB_tb = &#039;1&#039;)&lt;br /&gt;
	report &amp;quot;QB vart ikkje 1!&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
&lt;br /&gt;
--Ingen endring&lt;br /&gt;
S_tb &amp;lt;= &#039;1&#039;;&lt;br /&gt;
R_tb &amp;lt;= &#039;1&#039;;&lt;br /&gt;
wait for 100 ns;&lt;br /&gt;
&lt;br /&gt;
--Tester på feil verdier&lt;br /&gt;
assert (Q_tb = &#039;1&#039;)&lt;br /&gt;
	report &amp;quot;Endå meir feil&amp;quot;&lt;br /&gt;
	severity note;&lt;br /&gt;
&lt;br /&gt;
assert (QB_tb = &#039;0&#039;)&lt;br /&gt;
	report &amp;quot;hu, masse feil ja&amp;quot;&lt;br /&gt;
	severity Warning;&lt;br /&gt;
&lt;br /&gt;
--Reset&lt;br /&gt;
S_tb &amp;lt;= &#039;1&#039;;&lt;br /&gt;
R_tb &amp;lt;= &#039;0&#039;;&lt;br /&gt;
wait for 100 ns;&lt;br /&gt;
&lt;br /&gt;
assert (Q_tb = &#039;0&#039;)&lt;br /&gt;
	report &amp;quot;Q does not match the expected value!&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
&lt;br /&gt;
assert (QB_tb = &#039;1&#039;)&lt;br /&gt;
	report &amp;quot;QB does not match the expected value!&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
&lt;br /&gt;
--Set og reset&lt;br /&gt;
S_tb &amp;lt;= &#039;0&#039;;&lt;br /&gt;
R_tb &amp;lt;= &#039;0&#039;;&lt;br /&gt;
wait for 100 ns;&lt;br /&gt;
&lt;br /&gt;
assert (Q_tb = &#039;1&#039;)&lt;br /&gt;
	report &amp;quot;Q does not match the expected value!&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
&lt;br /&gt;
assert (QB_tb = &#039;1&#039;)&lt;br /&gt;
	report &amp;quot;QB does not match the expected value!&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
&lt;br /&gt;
--Oscillilerer&lt;br /&gt;
S_tb &amp;lt;= &#039;1&#039;;&lt;br /&gt;
R_tb &amp;lt;= &#039;1&#039;;&lt;br /&gt;
wait for 100 ns;&lt;br /&gt;
&lt;br /&gt;
assert (Q_tb = &#039;1&#039;)&lt;br /&gt;
	report &amp;quot;Q does not match the expected value!&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
&lt;br /&gt;
assert (QB_tb = &#039;0&#039;)&lt;br /&gt;
	report &amp;quot;QB does not match the expected value!&amp;quot;&lt;br /&gt;
	severity Error;&lt;br /&gt;
&lt;br /&gt;
end process;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For å kjøre igjennom hele filen bruker en&lt;br /&gt;
 run -all&lt;br /&gt;
&lt;br /&gt;
==Resultat==&lt;br /&gt;
Vi kan leggje inn feil for å få fram nokon feil for å vise forskjellige  feilmeldinger. Vi fekk også SR_latch til å oscillere.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# ** Error: Dette er ein feil&lt;br /&gt;
#    Time: 200 ns  Iteration: 0  Instance: :sr_tb&lt;br /&gt;
# ** Warning: Ein feil til&lt;br /&gt;
#    Time: 200 ns  Iteration: 0  Instance: :sr_tb&lt;br /&gt;
# ** Note: Endå meir feil&lt;br /&gt;
#    Time: 400 ns  Iteration: 0  Instance: :sr_tb&lt;br /&gt;
# ** Warning: hu, masse feil ja&lt;br /&gt;
#    Time: 400 ns  Iteration: 0  Instance: :sr_tb&lt;br /&gt;
# ** Error: (vsim-3601) Iteration limit reached at time 600 ns.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Om en legger til testbenk signalene i wave vinduet så får en opp markeringer der hvor det har oppstått feil, rød for error og gul for warning. En kan så trykke på markeringene og få opp feilmeldingen.&lt;br /&gt;
&lt;br /&gt;
==Konklusjon==&lt;br /&gt;
&lt;br /&gt;
Vi kan lage ein do-file som styrer stimuli under simulering, slik at vi slepp å skrive kommandoer kvar gang vi simulerer. Vi kan lage ein testbench for å simuler og kontrollere svaret mot forventa resultat. Med assert kan vi skrive ut feilmeldinger av ulike typer når det oppstår feil.&lt;br /&gt;
&lt;br /&gt;
[[Category:VHDL]] [[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Simulering_av_VHDL&amp;diff=2813</id>
		<title>Simulering av VHDL</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Simulering_av_VHDL&amp;diff=2813"/>
		<updated>2021-02-04T21:06:41Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: /* Starte Questa Sim */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Konstruksjon og simulering av VHDL-kode med Modelsim/Questa===&lt;br /&gt;
&lt;br /&gt;
==Innledning==&lt;br /&gt;
&lt;br /&gt;
Hensikten med denne oppgaven er å få et lite innblikk i bruk av høynivåspråk for simulering og uttesting av kretsløsninger. I denne oppgaven skal vi bruker VHDL (Very high speed integrated circuit Hardware Description Language), som er spesielt utviklet for elektronikk. VHDL er definert slik at det passer i en mengde sammenhenger, og er det vil derfor være uoverkommelig å gå inn på detaljer i denne oppgaven. Vi skal ta for oss noen eksempler:&lt;br /&gt;
&lt;br /&gt;
* Eksempel 1: Signalflyt i en SR-lås&lt;br /&gt;
&lt;br /&gt;
* Eksempel 2: Signaler og variable&lt;br /&gt;
&lt;br /&gt;
Et VHDL program består i hovedsak av ENTITY, som definerer tilkobling mellom programmet og omverden, og ARCHITECTURE, som definerer programmets funksjon. Den komplette VHDL-koden for eksempel 1 vist nederst på denne siden.Mentor Graphics har utviklet programvare (Modelsim//Questa) som gjør det mulig å beskrivem, simulere og feilsøke VHDL-kode. Fremgangsmåten for skriving, kompilering og simulering av VHDL-kode finner du under.&lt;br /&gt;
&lt;br /&gt;
==Starte Questa Sim==&lt;br /&gt;
Når man skal arbeide med Questa Sim fra Mentor Graphics skriv følgende kommando i et terminalvindu.&lt;br /&gt;
&lt;br /&gt;
 ssh -X mikroserver4&lt;br /&gt;
 export LM_LICENSE_FILE=1717@lisensserver&lt;br /&gt;
 source /eda/mentor/2019-20/scripts/PRECISION_2019.1.1_RHELx86.sh&lt;br /&gt;
 vsim&lt;br /&gt;
&lt;br /&gt;
==Lage et nytt prosjekt==&lt;br /&gt;
&lt;br /&gt;
I den følgende teksten er det vist hvordan man kan utføre kompilering, etc. på kommandolinjen. Dette kan enten gjøres i fra X terminalvinduet, eller fra kommandolinjen i Questa. Hvis man velger å bruke Questa-miljøet er de fleste prosedyrer/kommandoer tilgjengelige under menyen.&lt;br /&gt;
&lt;br /&gt;
Start et nytt prosjekt med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
File &amp;gt; New &amp;gt; Project&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:questa_new_project.png]]&lt;br /&gt;
&lt;br /&gt;
Velg et fornuftig navn og katalog. Man kan gjerne ha flere uavhengige vhdl-filer i et prosjekt.&lt;br /&gt;
Det er en fordel å ha en hovedkatalog til vhdl prosjektene og en underkatalog for prosjektet fex /home/bruker/vhdl_prosjekt/sr_latch&lt;br /&gt;
&lt;br /&gt;
==Skriving av VHDL kode==&lt;br /&gt;
&lt;br /&gt;
En ny VHDL kode (et design beskrevet med VHDL kode) påbegynnes med å starte emacs i terminal vinduet eller ved å bruke den innebygde teksteditoren i Questa ved å velge Create New File. &lt;br /&gt;
&lt;br /&gt;
Det fine med emacs er at man kan velge VHDL-modus. Dette gjøres med å skrive &#039;&#039;M-x vhdl-mode&#039;&#039; (M står for &#039;&#039;Meta&#039;&#039; og er vanligvis definert som esc-knappen). I emacs har en menyer med alle valg oppe langs kanten som i andre teksteditorer, men programmet skiller seg litt ut med kommandolinjen nederst i vinduet. Når en f. eks. skal lagre filen en har skrevet blir denne kommandolinjen aktiv og en skriver inn sti og filnavn der. Når man lagrer er ikke navnet på kodefilen viktig, men det er fornuftig å kalle den det samme som ENTITY-delen, med &#039;&#039;.vhdl&#039;&#039; som &amp;quot;etternavn&amp;quot; (f. eks. sr_latch.vhdl).&lt;br /&gt;
&lt;br /&gt;
==Kompilering av VHDL kode==&lt;br /&gt;
&lt;br /&gt;
Koden kompileres med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vcom sr_latch.vhdl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hvis det er feil i koden vil det komme en melding i kommando vinduet. Dobbeltklikker du på feilen vil du få opp en liste over kompileringsprosessen og alle feilene. Dobbeltklikker du så på linjen som angir en feil så vises den respektive linjen i editoren.&lt;br /&gt;
&lt;br /&gt;
Merk at navnet til det kompilerte designet blir skrevet med små bokstaver, selv om du har brukt store bokstaver i ENTITY- eller ARCHITECTURE-navnet. Det kompilerte designet blir liggende i work-katalogen.&lt;br /&gt;
&lt;br /&gt;
==Simulering og debugging i Questa==&lt;br /&gt;
&lt;br /&gt;
Når koden kompilerer feilfritt kan den simuleres i Questa. Dette startes med:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vsim&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nå dukker det opp en rute der du skal velge hva som skal simuleres, utvid work og velg vhdl filen. Eventuellt kan du skrive vsim work.sr_latch i kommandovinduet&lt;br /&gt;
&lt;br /&gt;
Questa bruker et standard X-basert vindusoppsett, og er derfor noen forskjellig fra de andre Mentor-programmene. Når du starter simulatoren åpnes det et vindu som vist i figur 1. Begynn med å åpne diverse vinduer:&lt;br /&gt;
&lt;br /&gt;
* View &amp;gt; Wave&lt;br /&gt;
&lt;br /&gt;
* View &amp;gt; Objects&lt;br /&gt;
&lt;br /&gt;
* View &amp;gt; Locals&lt;br /&gt;
&lt;br /&gt;
Man kan også gi kommandoer i Questa-vinduet. F.eks.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Wave *&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dra de signalene du vil se på i wave vinduet fra object vinduet.&lt;br /&gt;
&lt;br /&gt;
Signalverdier settes med kommandoen &#039;force&#039; eller med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Force &amp;gt; Force (i &amp;quot;Signals&amp;quot; vinduet)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dersom et av signalene skal være klokkesignal, kan dette gjøres enkelt med&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Force &amp;gt; Clock (i &amp;quot;Signals&amp;quot; vinduet)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Eksempler==&lt;br /&gt;
===Signalflyt i en SR-lås===&lt;br /&gt;
&lt;br /&gt;
Simuler SR-låsen. Begynn med å påtrykke stimuli til alle signaler ved tid 0 (t0). Bruk STEP-knappen for å simulere på delta-tid-nivå. (Om en holder musepekeren over knappene i Questa, kommer det en forklarende tekst opp.) Når verdiene er stabile kjører du i f.eks. 100 ns før du endrer stimuli (skriv &#039;&#039;run 100&#039;&#039; i et av vinduene). Tilsvarende kan du endre stimuli ved å skrive f.eks. &#039;&#039;force S 0&#039;&#039; i hoved-vinduet. Legg merke til den røde pilen som peker på den linjen som blir utført.&lt;br /&gt;
&lt;br /&gt;
Hvis du vil begynne på ny kan du velge&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
File &amp;gt; Restart -f&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.ALL;&lt;br /&gt;
&lt;br /&gt;
ENTITY SR_latch IS&lt;br /&gt;
PORT (&lt;br /&gt;
S,R  : IN std_logic ;&lt;br /&gt;
Q,QB : INOUT std_logic );&lt;br /&gt;
END SR_latch;&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE behave OF SR_latch IS&lt;br /&gt;
&lt;br /&gt;
BEGIN  --  behave&lt;br /&gt;
Q &amp;lt;= S nand QB;&lt;br /&gt;
QB &amp;lt;= R nand Q;&lt;br /&gt;
END behave;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Signaler og variable===&lt;br /&gt;
&lt;br /&gt;
Simuler VHDL-koden under. Bruk Step eller Step Over for å følge prosedyrens utvikling linje for linje. Simulere med optimaliseringsopsjon &amp;quot;-voptargs=+acc&amp;quot; for å kunne se variablene i wave-vinduet:&lt;br /&gt;
&lt;br /&gt;
 vsim -voptargs=+acc sign_var&lt;br /&gt;
&lt;br /&gt;
Bruk View &amp;gt; Objects for å kikke på signalene og View &amp;gt; Local for å se innholdet i variablene. Forklar endringene i signaler og variable. Hva er forskjellen som funksjon av tid/delta-tid?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.ALL;&lt;br /&gt;
&lt;br /&gt;
ENTITY sign_var IS&lt;br /&gt;
  PORT (clk  : IN std_logic);&lt;br /&gt;
END sign_var;&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE difference OF sign_var IS&lt;br /&gt;
&lt;br /&gt;
signal SA: bit := &#039;0&#039;;&lt;br /&gt;
signal SB: bit := &#039;1&#039;;&lt;br /&gt;
&lt;br /&gt;
begin  --  difference&lt;br /&gt;
p_test: process&lt;br /&gt;
  variable A: bit := &#039;0&#039;;&lt;br /&gt;
  variable B: bit := &#039;1&#039;;&lt;br /&gt;
  begin&lt;br /&gt;
    wait until rising_edge(clk);&lt;br /&gt;
    A := B;&lt;br /&gt;
    B := A;&lt;br /&gt;
    SA &amp;lt;= SB after 5 ns;&lt;br /&gt;
    SB &amp;lt;= SA after 5 ns;&lt;br /&gt;
  end process p_test;&lt;br /&gt;
end architecture difference;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2812</id>
		<title>Synthese av VHDL</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2812"/>
		<updated>2021-02-04T21:05:20Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Syntetiseringen av VHDL kode===&lt;br /&gt;
&lt;br /&gt;
Grunnen til at vi skal syntetisere koden, er at vi må lage beskrivelse av koden tilpassa ein krets.&lt;br /&gt;
&lt;br /&gt;
Vi vil no prøve å synthesisere vhdl kode. Og etterpå vil vi lage ein testbenk der vi samanliknar utsignala frå den syntetiserte og den opprinnelige koden. Vi bruker ein alu som eksempel.&lt;br /&gt;
&lt;br /&gt;
==Precision==&lt;br /&gt;
&lt;br /&gt;
Precision bruker Vivado til å syntetisere vhdl-koden. For å starte synteseprogrammet:&lt;br /&gt;
&lt;br /&gt;
 export LM_LICENSE_FILE=1717@lisensserver;2100@lisensserver&lt;br /&gt;
 source /eda/mentor/2019-20/scripts/PRECISION_2019.1.1_RHELx86.sh&lt;br /&gt;
 precision&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Vel deretter New Project, og deretter Add input file (i dette tilfelle add_sub_alu.vhd).&lt;br /&gt;
Så går vi inn på Setup design, velger ein kretsprodusent, den ønska kretsen og designfrekvens, for eksempel Zynq med frekvens 200MHz. For å få ut en vhdl fil av den syntetiserte koden må en gå på Tools-&amp;gt;Options-&amp;gt;Output og hak av for VHDL og trykk ok.&lt;br /&gt;
&lt;br /&gt;
Pass på at Precision finner Vivado, settes i menyen:&lt;br /&gt;
 Tools &amp;gt; Options &amp;gt; Place and Route Settings&lt;br /&gt;
deretter&lt;br /&gt;
 Vivado &amp;gt; Integrated Place and Route &amp;gt; path to Xilinx Vivado installation tree&lt;br /&gt;
settes til&lt;br /&gt;
 /eda/xilinx/Vivado/2020.2&lt;br /&gt;
&lt;br /&gt;
Trykk så compile, og synthesize. &lt;br /&gt;
No kan vi sjå på den generte kretsen i RTL Schematic og Technology Schematic (syntese med den valgte kretsen) under Schematics på venstre side.&lt;br /&gt;
&lt;br /&gt;
==Questasim==&lt;br /&gt;
&lt;br /&gt;
Start opp Questasim, lag nytt prosjekt og legg til vhdl fila (add_sub_alu.vhdl). Så legg vi til fila som Precision generte i prosjektdir til &#039;precision/prosjektnavn_temp_1/prosjektnavn.vhd&#039; (i vårt tilfelle &#039;alu/add_sub_alu_temp_1/add_sub_alu.vhd&#039;).&lt;br /&gt;
&lt;br /&gt;
Vi trenger simuleringsbibliotek for den valgte kretsfamilien for å kunne simulere etter &amp;quot;Place and Route&amp;quot;. Disse bibliotekene kan genereres fra Vivado med menyen&lt;br /&gt;
 Tools &amp;gt; Compile Simulation Libraries&lt;br /&gt;
men, vi har kompilert disse unisim-bibliotekene til mappen /eda/xilinx/lib. Du kan &amp;quot;mappe&amp;quot; disse slik:&lt;br /&gt;
&lt;br /&gt;
 vmap unisim /eda/xilinx/lib/unisim&lt;br /&gt;
 &lt;br /&gt;
Deretter legger vi til ei ny vhdl fil der vi skal lage testbenken vår. Vi legger til ein komponent av den opprinnelige og den synthesiserte vhdl koden. Vi koblar alle inngangane til samme signal på testbenken, og gir ut 2 forskjellige utsignal for å samanlikne ved hjelp av assert(sjå fila alu_tb.vhdl). På grunn av at utsignala av dei to komponentane ikkje skifta heilt synkront, testa vi berre kvart nanosekund ved å putta assert inn i ein process med wait for 1ns:&lt;br /&gt;
&lt;br /&gt;
 test : process&lt;br /&gt;
 begin&lt;br /&gt;
 wait for 1 ns;&lt;br /&gt;
 assert (data_out = data_out_synt)&lt;br /&gt;
 report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
 severity Error;&lt;br /&gt;
 end process test;&lt;br /&gt;
&lt;br /&gt;
Når vi har laga testbenken, kompilerer vi filene (husk å kompilere i rett rekkefølge med compileorder-&amp;gt;autogenerate første gong).&lt;br /&gt;
&lt;br /&gt;
Siden precision generer samme navn på entityen og architecturen på den syntetiserte filen som i den orginale så vil ikke simulatoren kjøre de samtidig. Dette endres ved å endre entity fra add_sub_alu til add_sub_alu_synth og skifte navnet på architecture fra algoritm til structure øverst og nederst i den syntetiserte filen.&lt;br /&gt;
&lt;br /&gt;
==Simulering med timing==&lt;br /&gt;
&lt;br /&gt;
Eksempel på start av simulering med timing:&lt;br /&gt;
&lt;br /&gt;
 vsim -t ps alu_tb -sdfmax :alu_tb:ali=/heim/yngve/vhdl/syntese/alu_temp_1/simulation/modelsim/add_sub_alu_vhd.sdo&lt;br /&gt;
&lt;br /&gt;
Vi kan sjå at i dei første 50 nanosekunda er utsignala ulike. Dette er fordi før første klokkeflanke er verdiane udefinert i den opprinnelige komponenten, medan den synthesisere ikkje kan ha udefinerte verdiar. I Questasim vil vi derfor få ein del feilmeldingar dei første 50 nanosekunda.&lt;br /&gt;
&lt;br /&gt;
==Konklusjon==&lt;br /&gt;
&lt;br /&gt;
Vi kan teste om den syntesiserte komponenten oppfører seg likt med den opprinnelige komponenten ved å koble begge to til samme testbenk. Vi fekk problem i overgangane når vi testa kontinuerlig, så vi løyste problemet ved å berre teste kvart naonosekund. Bortsett frå dei første 50 nanosekunda (sjå grunn over) kan vi sjå at begge komponetane gir ut samme utsignal. Vi prøvde å bruke samme enitynavn på begge komponentane med ulik arcitechture, men fekk berre lov å kompilere og ikkje simulere. Vi kan derfor konkludere med at desse må ha ulike navn.&lt;br /&gt;
&lt;br /&gt;
==Kode==&lt;br /&gt;
&lt;br /&gt;
===Kode til add_sub_alu.vhd===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.All;&lt;br /&gt;
USE ieee.std_logic_unsigned.all;&lt;br /&gt;
&lt;br /&gt;
ENTITY add_sub_alu IS&lt;br /&gt;
PORT (&lt;br /&gt;
  clk         : IN  std_logic;&lt;br /&gt;
  rst         : IN  std_logic;&lt;br /&gt;
  enable_in   : IN  std_logic;&lt;br /&gt;
  start       : IN  std_logic;&lt;br /&gt;
  enable      : IN  std_logic;&lt;br /&gt;
  do_add      : IN  std_logic;&lt;br /&gt;
  do_subtract : IN  std_logic;&lt;br /&gt;
  do_hold     : IN  std_logic;&lt;br /&gt;
  data_in     : IN  std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  data_out    : OUT std_logic_vector(3 DOWNTO 0) BUS);&lt;br /&gt;
END add_sub_alu;&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE algorithm OF add_sub_alu IS&lt;br /&gt;
  TYPE   states          IS (hold, reset, add, subtract);&lt;br /&gt;
  SIGNAL state_var       : states;&lt;br /&gt;
  SIGNAL reg, int_reg    : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  SIGNAL latched_data_in : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
BEGIN&lt;br /&gt;
&lt;br /&gt;
latch: PROCESS (enable_in, data_in)is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (enable_in = &#039;1&#039;) THEN&lt;br /&gt;
    latched_data_in &amp;lt;= data_in;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS latch;&lt;br /&gt;
&lt;br /&gt;
fsm: PROCESS (clk, rst) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (rst = &#039;0&#039;) THEN&lt;br /&gt;
    state_var &amp;lt;= reset;&lt;br /&gt;
  ELSIF rising_edge(clk) THEN&lt;br /&gt;
    CASE state_var IS&lt;br /&gt;
      WHEN hold =&amp;gt;&lt;br /&gt;
        IF (start = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= reset;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN reset    =&amp;gt;&lt;br /&gt;
        IF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN add      =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN subtract =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN OTHERS =&amp;gt; state_var &amp;lt;= reset;&lt;br /&gt;
    END CASE;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS fsm;&lt;br /&gt;
&lt;br /&gt;
alu: PROCESS (state_var, latched_data_in, reg)is&lt;br /&gt;
BEGIN&lt;br /&gt;
CASE state_var IS&lt;br /&gt;
  WHEN add      =&amp;gt; int_reg &amp;lt;= reg + latched_data_in;&lt;br /&gt;
  WHEN subtract =&amp;gt; int_reg &amp;lt;= reg - latched_data_in;&lt;br /&gt;
  WHEN reset    =&amp;gt; int_reg &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
  WHEN hold     =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
  WHEN OTHERS   =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
END CASE;&lt;br /&gt;
END PROCESS alu;&lt;br /&gt;
&lt;br /&gt;
mem: PROCESS (clk) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF rising_edge(clk) THEN&lt;br /&gt;
    reg &amp;lt;= int_reg;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS mem;&lt;br /&gt;
&lt;br /&gt;
tri: PROCESS (enable, reg) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  FOR i IN 3 DOWNTO 0 LOOP&lt;br /&gt;
    IF (enable = &#039;1&#039;) THEN&lt;br /&gt;
      data_out(i) &amp;lt;= reg(i);&lt;br /&gt;
    ELSE&lt;br /&gt;
      data_out(i) &amp;lt;= &#039;Z&#039;;&lt;br /&gt;
    END IF;&lt;br /&gt;
  END LOOP;&lt;br /&gt;
END PROCESS tri;&lt;br /&gt;
&lt;br /&gt;
END algorithm;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Koden til alu_tb.vhdl===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library ieee;&lt;br /&gt;
use ieee.std_logic_1164.all;&lt;br /&gt;
library work;&lt;br /&gt;
use work.all;&lt;br /&gt;
&lt;br /&gt;
entity alu_tb is&lt;br /&gt;
end entity alu_tb;&lt;br /&gt;
&lt;br /&gt;
architecture struct of alu_tb is&lt;br /&gt;
--Deklaring av signal som skal koblast til komponentane.&lt;br /&gt;
--Alle innsignal er felles, medan vi har 2 forskjellige utsignal.&lt;br /&gt;
signal clk, reset : std_logic;&lt;br /&gt;
signal enable_in : std_logic;&lt;br /&gt;
signal start : std_logic;&lt;br /&gt;
signal enable : std_logic;&lt;br /&gt;
signal do_add : std_logic;&lt;br /&gt;
signal do_subtract : std_logic;&lt;br /&gt;
signal do_hold : std_logic;&lt;br /&gt;
signal data_in : std_logic_vector(3 downto 0);&lt;br /&gt;
signal data_out : std_logic_vector(3 downto 0);&lt;br /&gt;
signal data_out_synt : std_logic_vector(3 downto 0);&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
--Deklarer komponenten alu.&lt;br /&gt;
alu : entity add_sub_alu(algorithm)&lt;br /&gt;
&lt;br /&gt;
--Kobler signala til den opprinnelige komponenten.&lt;br /&gt;
port map (&lt;br /&gt;
clk =&amp;gt; clk,&lt;br /&gt;
rst =&amp;gt; reset,&lt;br /&gt;
enable_in =&amp;gt; enable_in,&lt;br /&gt;
start =&amp;gt; start,&lt;br /&gt;
enable =&amp;gt; enable,&lt;br /&gt;
do_add =&amp;gt; do_add,&lt;br /&gt;
do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
do_hold =&amp;gt; do_hold,&lt;br /&gt;
data_in =&amp;gt; data_in,&lt;br /&gt;
data_out =&amp;gt; data_out);&lt;br /&gt;
&lt;br /&gt;
--Deklarer komponenten alu_synt.&lt;br /&gt;
alu_synt : entity add_sub_alu_synth(structure)&lt;br /&gt;
&lt;br /&gt;
--Kobler signala til den synthiserte komponenten.&lt;br /&gt;
port map (&lt;br /&gt;
clk =&amp;gt; clk,&lt;br /&gt;
rst =&amp;gt; reset,&lt;br /&gt;
enable_in =&amp;gt; enable_in,&lt;br /&gt;
start =&amp;gt; start,&lt;br /&gt;
enable =&amp;gt; enable,&lt;br /&gt;
do_add =&amp;gt; do_add,&lt;br /&gt;
do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
do_hold =&amp;gt; do_hold,&lt;br /&gt;
data_in =&amp;gt; data_in,&lt;br /&gt;
data_out =&amp;gt; data_out_synt);&lt;br /&gt;
&lt;br /&gt;
--Klokkegenerator&lt;br /&gt;
clock_gen : process&lt;br /&gt;
begin&lt;br /&gt;
clk &amp;lt;= &#039;0&#039;, &#039;1&#039; after 50 ns;&lt;br /&gt;
wait for 100 ns;&lt;br /&gt;
end process clock_gen;&lt;br /&gt;
&lt;br /&gt;
--Setter testvektorane.&lt;br /&gt;
reset &amp;lt;= &#039;0&#039;, &#039;1&#039; after 60 ns;&lt;br /&gt;
enable &amp;lt;= &#039;1&#039;, &#039;0&#039; after 900 ns;&lt;br /&gt;
enable_in &amp;lt;= &#039;1&#039;, &#039;0&#039; after 400 ns;&lt;br /&gt;
start &amp;lt;= &#039;1&#039;, &#039;0&#039; after 300 ns;&lt;br /&gt;
do_add &amp;lt;= &#039;1&#039;, &#039;0&#039; after 660 ns;&lt;br /&gt;
do_subtract &amp;lt;= &#039;0&#039;;&lt;br /&gt;
do_hold &amp;lt;= &#039;0&#039;;&lt;br /&gt;
data_in &amp;lt;= X&amp;quot;3&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
--Test process for å samanlikne utsignala kvart nanosekund.&lt;br /&gt;
test : process&lt;br /&gt;
begin&lt;br /&gt;
wait for 1 ns;&lt;br /&gt;
assert (data_out = data_out_synt)&lt;br /&gt;
report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
severity Error;&lt;br /&gt;
end process test;&lt;br /&gt;
&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Modelsim/Questa&amp;diff=2811</id>
		<title>Modelsim/Questa</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Modelsim/Questa&amp;diff=2811"/>
		<updated>2021-02-04T21:02:47Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Simulering av VHDL]]&lt;br /&gt;
&lt;br /&gt;
[[VHDL Testbenk]]&lt;br /&gt;
&lt;br /&gt;
[[Synthese av VHDL]]&lt;br /&gt;
&lt;br /&gt;
== Referanselitteratur ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/VHDL Wikipedia:VHDL]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
[http://www.ashenden.com.au/ Ashenden Designs] &lt;br /&gt;
dead link&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
[http://freerangefactory.org/books_tuts.html Free Range VHDL textbook]&lt;br /&gt;
&lt;br /&gt;
[http://esd.cs.ucr.edu/labs/tutorial/ VHDL Tutorial: Learn by Example]&lt;br /&gt;
&lt;br /&gt;
[http://www.ioenotes.edu.np/media/notes/embedded-system/vhdl.pdf VHDL Quick Start (slides by Ashenden)]&lt;br /&gt;
&lt;br /&gt;
[http://model.com/content/modelsim-pe-simulation-and-debug Modelsim]&lt;br /&gt;
&lt;br /&gt;
[http://m.eet.com/media/1151614/23798-46098.pdf 10 tips for generating reusable VHDL]&lt;br /&gt;
&lt;br /&gt;
[http://www.actel.com/documents/hdlcode_ug.pdf Actel HDL coding Style Guide]&lt;br /&gt;
&lt;br /&gt;
[http://www.seas.upenn.edu/~ese171/vhdl/vhdl_primer.html VHDL primer]&lt;br /&gt;
&lt;br /&gt;
[https://bitvis.no/dev-tools/uvvm/ Bitvis Universal VHDL Verification Methodology ]&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2810</id>
		<title>Synthese av VHDL</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2810"/>
		<updated>2021-02-04T13:48:16Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Syntetiseringen av VHDL kode===&lt;br /&gt;
&lt;br /&gt;
Grunnen til at vi skal syntetisere koden, er at vi må lage beskrivelse av koden tilpassa ein krets.&lt;br /&gt;
&lt;br /&gt;
Vi vil no prøve å synthesisere vhdl kode. Og etterpå vil vi lage ein testbenk der vi samanliknar utsignala frå den syntetiserte og den opprinnelige koden. Vi bruker ein alu som eksempel.&lt;br /&gt;
&lt;br /&gt;
==Precision==&lt;br /&gt;
&lt;br /&gt;
Precision bruker Vivado til å syntetisere vhdl-koden. For å starte synteseprogrammet:&lt;br /&gt;
&lt;br /&gt;
 export LM_LICENSE_FILE=1717@lisensserver;2100@lisensserver&lt;br /&gt;
 source /eda/mentor/2019-20/scripts/PRECISION_2019.1.1_RHELx86.sh&lt;br /&gt;
 precision&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Vel deretter New Project, og deretter Add input file (i dette tilfelle add_sub_alu.vhd).&lt;br /&gt;
Så går vi inn på Setup design, velger ein kretsprodusent, den ønska kretsen og designfrekvens, for eksempel Zynq med frekvens 200MHz. For å få ut en vhdl fil av den syntetiserte koden må en gå på Tools-&amp;gt;Options-&amp;gt;Output og hak av for VHDL og trykk ok.&lt;br /&gt;
&lt;br /&gt;
Pass på at Precision finner Vivado, settes i menyen:&lt;br /&gt;
 Tools &amp;gt; Options &amp;gt; Place and Route Settings&lt;br /&gt;
deretter&lt;br /&gt;
 Vivado &amp;gt; Integrated Place and Route &amp;gt; path to Xilinx Vivado installation tree&lt;br /&gt;
settes til&lt;br /&gt;
 /eda/xilinx/Vivado/2020.2&lt;br /&gt;
&lt;br /&gt;
Trykk så compile, og synthesize. &lt;br /&gt;
No kan vi sjå på den generte kretsen i RTL Schematic og Technology Schematic (syntese med den valgte kretsen) under Schematics på venstre side.&lt;br /&gt;
&lt;br /&gt;
==Questasim==&lt;br /&gt;
&lt;br /&gt;
Start opp Questasim, lag nytt prosjekt og legg til vhdl fila (add_sub_alu.vhdl). Så legg vi til fila som Precision generte i prosjektdir til &#039;precision/prosjektnavn_temp_1/prosjektnavn.vhd&#039; (i vårt tilfelle &#039;alu/add_sub_alu_temp_1/add_sub_alu.vhd&#039;).&lt;br /&gt;
&lt;br /&gt;
Vi trenger simuleringsbibliotek for den valgte kretsfamilien for å kunne simulere etter &amp;quot;Place and Route&amp;quot;. Disse bibliotekene kan genereres fra Vivado med menyen&lt;br /&gt;
 Tools &amp;gt; Compile Simulation Libraries&lt;br /&gt;
men, vi har kompilert disse unisim-bibliotekene til mappen /eda/xilinx/lib. Du kan &amp;quot;mappe&amp;quot; disse slik:&lt;br /&gt;
&lt;br /&gt;
 vmap unisim /eda/xilinx/lib/unisim&lt;br /&gt;
 &lt;br /&gt;
Deretter legger vi til ei ny vhdl fil der vi skal lage testbenken vår. Vi legger til ein komponent av den opprinnelige og den synthesiserte vhdl koden. Vi koblar alle inngangane til samme signal på testbenken, og gir ut 2 forskjellige utsignal for å samanlikne ved hjelp av assert(sjå fila alu_tb.vhdl). På grunn av at utsignala av dei to komponentane ikkje skifta heilt synkront, testa vi berre kvart nanosekund ved å putta assert inn i ein process med wait for 1ns:&lt;br /&gt;
&lt;br /&gt;
 test : process&lt;br /&gt;
 begin&lt;br /&gt;
 wait for 1 ns;&lt;br /&gt;
 assert (data_out = data_out_synt)&lt;br /&gt;
 report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
 severity Error;&lt;br /&gt;
 end process test;&lt;br /&gt;
&lt;br /&gt;
Når vi har laga testbenken, kompilerer vi filene (husk å kompilere i rett rekkefølge med compileorder-&amp;gt;autogenerate første gong).&lt;br /&gt;
&lt;br /&gt;
Siden precision generer samme navn på entityen og architecturen på den syntetiserte filen som i den orginale så vil ikke simulatoren kjøre de samtidig. Dette endres ved å endre entity fra add_sub_alu til add_sub_alu_synth og skifte navnet på architecture fra algoritm til structure øverst og nederst i den syntetiserte filen.&lt;br /&gt;
&lt;br /&gt;
==Simulering med timing==&lt;br /&gt;
&lt;br /&gt;
Eksempel på start av simulering med timing:&lt;br /&gt;
&lt;br /&gt;
 vsim -t ps alu_tb -sdfmax :alu_tb:ali=/heim/yngve/vhdl/syntese/alu_temp_1/simulation/modelsim/add_sub_alu_vhd.sdo&lt;br /&gt;
&lt;br /&gt;
Vi kan sjå at i dei første 50 nanosekunda er utsignala ulike. Dette er fordi før første klokkeflanke er verdiane udefinert i den opprinnelige komponenten, medan den synthesisere ikkje kan ha udefinerte verdiar. I Modelsim vil vi derfor få ein del feilmeldingar dei første 50 nanosekunda.&lt;br /&gt;
&lt;br /&gt;
==Konklusjon==&lt;br /&gt;
&lt;br /&gt;
Vi kan teste om den synthesisere komponenten oppfører seg likt med den opprinnelige komponenten ved å koble begge to til samme testbenk. Vi fekk problem i overgangane når vi testa kontinuerlig, så vi løyste problemet ved å berre teste kvart naonosekund. Bortsett frå dei første 50 nanosekunda (sjå grunn over) kan vi sjå at begge komponetane gir ut samme utsignal. Vi prøvde å bruke samme enitynavn på begge komponentane med ulik arcitechture, men fekk berre lov å kompilere og ikkje simulere. Vi kan derfor konkludere med at desse må ha ulike navn.&lt;br /&gt;
&lt;br /&gt;
==Kode==&lt;br /&gt;
&lt;br /&gt;
===Kode til add_sub_alu.vhd===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.All;&lt;br /&gt;
USE ieee.std_logic_unsigned.all;&lt;br /&gt;
&lt;br /&gt;
ENTITY add_sub_alu IS&lt;br /&gt;
PORT (&lt;br /&gt;
  clk         : IN  std_logic;&lt;br /&gt;
  rst         : IN  std_logic;&lt;br /&gt;
  enable_in   : IN  std_logic;&lt;br /&gt;
  start       : IN  std_logic;&lt;br /&gt;
  enable      : IN  std_logic;&lt;br /&gt;
  do_add      : IN  std_logic;&lt;br /&gt;
  do_subtract : IN  std_logic;&lt;br /&gt;
  do_hold     : IN  std_logic;&lt;br /&gt;
  data_in     : IN  std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  data_out    : OUT std_logic_vector(3 DOWNTO 0) BUS);&lt;br /&gt;
END add_sub_alu;&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE algorithm OF add_sub_alu IS&lt;br /&gt;
  TYPE   states          IS (hold, reset, add, subtract);&lt;br /&gt;
  SIGNAL state_var       : states;&lt;br /&gt;
  SIGNAL reg, int_reg    : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  SIGNAL latched_data_in : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
BEGIN&lt;br /&gt;
&lt;br /&gt;
latch: PROCESS (enable_in, data_in)is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (enable_in = &#039;1&#039;) THEN&lt;br /&gt;
    latched_data_in &amp;lt;= data_in;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS latch;&lt;br /&gt;
&lt;br /&gt;
fsm: PROCESS (clk, rst) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (rst = &#039;0&#039;) THEN&lt;br /&gt;
    state_var &amp;lt;= reset;&lt;br /&gt;
  ELSIF rising_edge(clk) THEN&lt;br /&gt;
    CASE state_var IS&lt;br /&gt;
      WHEN hold =&amp;gt;&lt;br /&gt;
        IF (start = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= reset;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN reset    =&amp;gt;&lt;br /&gt;
        IF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN add      =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN subtract =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN OTHERS =&amp;gt; state_var &amp;lt;= reset;&lt;br /&gt;
    END CASE;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS fsm;&lt;br /&gt;
&lt;br /&gt;
alu: PROCESS (state_var, latched_data_in, reg)is&lt;br /&gt;
BEGIN&lt;br /&gt;
CASE state_var IS&lt;br /&gt;
  WHEN add      =&amp;gt; int_reg &amp;lt;= reg + latched_data_in;&lt;br /&gt;
  WHEN subtract =&amp;gt; int_reg &amp;lt;= reg - latched_data_in;&lt;br /&gt;
  WHEN reset    =&amp;gt; int_reg &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
  WHEN hold     =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
  WHEN OTHERS   =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
END CASE;&lt;br /&gt;
END PROCESS alu;&lt;br /&gt;
&lt;br /&gt;
mem: PROCESS (clk) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF rising_edge(clk) THEN&lt;br /&gt;
    reg &amp;lt;= int_reg;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS mem;&lt;br /&gt;
&lt;br /&gt;
tri: PROCESS (enable, reg) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  FOR i IN 3 DOWNTO 0 LOOP&lt;br /&gt;
    IF (enable = &#039;1&#039;) THEN&lt;br /&gt;
      data_out(i) &amp;lt;= reg(i);&lt;br /&gt;
    ELSE&lt;br /&gt;
      data_out(i) &amp;lt;= &#039;Z&#039;;&lt;br /&gt;
    END IF;&lt;br /&gt;
  END LOOP;&lt;br /&gt;
END PROCESS tri;&lt;br /&gt;
&lt;br /&gt;
END algorithm;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Koden til alu_tb.vhdl===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library ieee;&lt;br /&gt;
use ieee.std_logic_1164.all;&lt;br /&gt;
library work;&lt;br /&gt;
use work.all;&lt;br /&gt;
&lt;br /&gt;
entity alu_tb is&lt;br /&gt;
end entity alu_tb;&lt;br /&gt;
&lt;br /&gt;
architecture struct of alu_tb is&lt;br /&gt;
--Deklaring av signal som skal koblast til komponentane.&lt;br /&gt;
--Alle innsignal er felles, medan vi har 2 forskjellige utsignal.&lt;br /&gt;
signal clk, reset : std_logic;&lt;br /&gt;
signal enable_in : std_logic;&lt;br /&gt;
signal start : std_logic;&lt;br /&gt;
signal enable : std_logic;&lt;br /&gt;
signal do_add : std_logic;&lt;br /&gt;
signal do_subtract : std_logic;&lt;br /&gt;
signal do_hold : std_logic;&lt;br /&gt;
signal data_in : std_logic_vector(3 downto 0);&lt;br /&gt;
signal data_out : std_logic_vector(3 downto 0);&lt;br /&gt;
signal data_out_synt : std_logic_vector(3 downto 0);&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
--Deklarer komponenten alu.&lt;br /&gt;
alu : entity add_sub_alu(algorithm)&lt;br /&gt;
&lt;br /&gt;
--Kobler signala til den opprinnelige komponenten.&lt;br /&gt;
port map (&lt;br /&gt;
clk =&amp;gt; clk,&lt;br /&gt;
rst =&amp;gt; reset,&lt;br /&gt;
enable_in =&amp;gt; enable_in,&lt;br /&gt;
start =&amp;gt; start,&lt;br /&gt;
enable =&amp;gt; enable,&lt;br /&gt;
do_add =&amp;gt; do_add,&lt;br /&gt;
do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
do_hold =&amp;gt; do_hold,&lt;br /&gt;
data_in =&amp;gt; data_in,&lt;br /&gt;
data_out =&amp;gt; data_out);&lt;br /&gt;
&lt;br /&gt;
--Deklarer komponenten alu_synt.&lt;br /&gt;
alu_synt : entity add_sub_alu_synth(structure)&lt;br /&gt;
&lt;br /&gt;
--Kobler signala til den synthiserte komponenten.&lt;br /&gt;
port map (&lt;br /&gt;
clk =&amp;gt; clk,&lt;br /&gt;
rst =&amp;gt; reset,&lt;br /&gt;
enable_in =&amp;gt; enable_in,&lt;br /&gt;
start =&amp;gt; start,&lt;br /&gt;
enable =&amp;gt; enable,&lt;br /&gt;
do_add =&amp;gt; do_add,&lt;br /&gt;
do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
do_hold =&amp;gt; do_hold,&lt;br /&gt;
data_in =&amp;gt; data_in,&lt;br /&gt;
data_out =&amp;gt; data_out_synt);&lt;br /&gt;
&lt;br /&gt;
--Klokkegenerator&lt;br /&gt;
clock_gen : process&lt;br /&gt;
begin&lt;br /&gt;
clk &amp;lt;= &#039;0&#039;, &#039;1&#039; after 50 ns;&lt;br /&gt;
wait for 100 ns;&lt;br /&gt;
end process clock_gen;&lt;br /&gt;
&lt;br /&gt;
--Setter testvektorane.&lt;br /&gt;
reset &amp;lt;= &#039;0&#039;, &#039;1&#039; after 60 ns;&lt;br /&gt;
enable &amp;lt;= &#039;1&#039;, &#039;0&#039; after 900 ns;&lt;br /&gt;
enable_in &amp;lt;= &#039;1&#039;, &#039;0&#039; after 400 ns;&lt;br /&gt;
start &amp;lt;= &#039;1&#039;, &#039;0&#039; after 300 ns;&lt;br /&gt;
do_add &amp;lt;= &#039;1&#039;, &#039;0&#039; after 660 ns;&lt;br /&gt;
do_subtract &amp;lt;= &#039;0&#039;;&lt;br /&gt;
do_hold &amp;lt;= &#039;0&#039;;&lt;br /&gt;
data_in &amp;lt;= X&amp;quot;3&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
--Test process for å samanlikne utsignala kvart nanosekund.&lt;br /&gt;
test : process&lt;br /&gt;
begin&lt;br /&gt;
wait for 1 ns;&lt;br /&gt;
assert (data_out = data_out_synt)&lt;br /&gt;
report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
severity Error;&lt;br /&gt;
end process test;&lt;br /&gt;
&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2809</id>
		<title>Synthese av VHDL</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2809"/>
		<updated>2021-02-04T13:46:34Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: /* Precision */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Syntetiseringen av VHDL kode===&lt;br /&gt;
&lt;br /&gt;
Grunnen til at vi skal syntetisere koden, er at vi må lage beskrivelse av koden tilpassa ein krets.&lt;br /&gt;
&lt;br /&gt;
Vi vil no prøve å synthesisere vhdl kode. Og etterpå vil vi lage ein testbenk der vi samanliknar utsignala frå den syntetiserte og den opprinnelige koden. Vi bruker ein alu som eksempel.&lt;br /&gt;
&lt;br /&gt;
==Precision==&lt;br /&gt;
&lt;br /&gt;
Precision bruker Vivado til å syntetisere vhdl-koden. For å starte synteseprogrammet:&lt;br /&gt;
&lt;br /&gt;
 export LM_LICENSE_FILE=1717@lisensserver;2100@lisensserver&lt;br /&gt;
 source /eda/mentor/2019-20/scripts/PRECISION_2019.1.1_RHELx86.sh&lt;br /&gt;
 precision&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Vel deretter New Project, og deretter Add input file(i dette tilfelle add_sub_alu.vhd).&lt;br /&gt;
Så går vi inn på Setup design, velger ein kretsprodusent, den ønska kretsen og designfrekvens, for eksempel Zynq med frekvens 200MHz. For å få ut en vhdl fil av den syntetiserte koden må en gå på Tools-&amp;gt;Options-&amp;gt;Output og hak av for VHDL og trykk ok.&lt;br /&gt;
&lt;br /&gt;
Pass på at Precision finner Vivado, settes i menyen:&lt;br /&gt;
 Tools &amp;gt; Options &amp;gt; Place and Route Settings&lt;br /&gt;
deretter&lt;br /&gt;
 Vivado &amp;gt; Integrated Place and Route &amp;gt; path to Xilinx Vivado installation tree&lt;br /&gt;
settes til&lt;br /&gt;
 /eda/xilinx/Vivado/2020.2&lt;br /&gt;
&lt;br /&gt;
Trykk så compile, og synthesize. &lt;br /&gt;
No kan vi sjå på den generte kretsen i RTL Schematic og Technology Schematic(syntese med den valgte kretsen) under Schematics på venstre side.&lt;br /&gt;
&lt;br /&gt;
==Questasim==&lt;br /&gt;
&lt;br /&gt;
Start opp Questasim, lag nytt prosjekt og legg til vhdl fila(add_sub_alu.vhdl). Så legg vi til fila som Precision generte i prosjektdir til &#039;precision/prosjektnavn_temp_1/prosjektnavn.vhd&#039; (i vårt tilfelle &#039;alu/add_sub_alu_temp_1/add_sub_alu.vhd&#039;).&lt;br /&gt;
&lt;br /&gt;
Vi trenger simuleringsbibliotek for den valgte kretsfamilien for å kunne simulere etter &amp;quot;Place and Route&amp;quot;. Disse bibliotekene kan genereres fra Vivado med menyen&lt;br /&gt;
 Tools &amp;gt; Compile Simulation Libraries&lt;br /&gt;
men, vi har kompilert disse unisim-bibliotekene til mappen /eda/xilinx/lib. Du kan &amp;quot;mappe&amp;quot; disse slik:&lt;br /&gt;
&lt;br /&gt;
 vmap unisim /eda/xilinx/lib/unisim&lt;br /&gt;
 &lt;br /&gt;
Deretter legger vi til ei ny vhdl fil der vi skal lage testbenken vår. Vi legger til ein komponent av den opprinnelige og den synthesiserte vhdl koden. Vi koblar alle inngangane til samme signal på testbenken, og gir ut 2 forskjellige utsignal for å samanlikne ved hjelp av assert(sjå fila alu_tb.vhdl). På grunn av at utsignala av dei to komponentane ikkje skifta heilt synkront, testa vi berre kvart nanosekund ved å putta assert inn i ein process med wait for 1ns:&lt;br /&gt;
&lt;br /&gt;
 test : process&lt;br /&gt;
 begin&lt;br /&gt;
 wait for 1 ns;&lt;br /&gt;
 assert (data_out = data_out_synt)&lt;br /&gt;
 report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
 severity Error;&lt;br /&gt;
 end process test;&lt;br /&gt;
&lt;br /&gt;
Når vi har laga testbenken, kompilerer vi filene (husk å kompilere i rett rekkefølge med compileorder-&amp;gt;autogenerate første gong).&lt;br /&gt;
&lt;br /&gt;
Siden precision generer samme navn på entityen og architecturen på den syntetiserte filen som i den orginale så vil ikke simulatoren kjøre de samtidig. Dette endres ved å endre entity fra add_sub_alu til add_sub_alu_synth og skifte navnet på architecture fra algoritm til structure øverst og nederst i den syntetiserte filen.&lt;br /&gt;
&lt;br /&gt;
==Simulering med timing==&lt;br /&gt;
&lt;br /&gt;
Eksempel på start av simulering med timing:&lt;br /&gt;
&lt;br /&gt;
 vsim -t ps alu_tb -sdfmax :alu_tb:ali=/heim/yngve/vhdl/syntese/alu_temp_1/simulation/modelsim/add_sub_alu_vhd.sdo&lt;br /&gt;
&lt;br /&gt;
Vi kan sjå at i dei første 50 nanosekunda er utsignala ulike. Dette er fordi før første klokkeflanke er verdiane udefinert i den opprinnelige komponenten, medan den synthesisere ikkje kan ha udefinerte verdiar. I Modelsim vil vi derfor få ein del feilmeldingar dei første 50 nanosekunda.&lt;br /&gt;
&lt;br /&gt;
==Konklusjon==&lt;br /&gt;
&lt;br /&gt;
Vi kan teste om den synthesisere komponenten oppfører seg likt med den opprinnelige komponenten ved å koble begge to til samme testbenk. Vi fekk problem i overgangane når vi testa kontinuerlig, så vi løyste problemet ved å berre teste kvart naonosekund. Bortsett frå dei første 50 nanosekunda(sjå grunn over) kan vi sjå at begge komponetane gir ut samme utsignal. Vi prøvde å bruke samme enitynavn på begge komponentane med ulik arcitechture, men fekk berre lov å kompilere og ikkje simulere. Vi kan derfor konkludere med at desse må ha ulike navn.&lt;br /&gt;
&lt;br /&gt;
==Kode==&lt;br /&gt;
&lt;br /&gt;
===Kode til add_sub_alu.vhd===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.All;&lt;br /&gt;
USE ieee.std_logic_unsigned.all;&lt;br /&gt;
&lt;br /&gt;
ENTITY add_sub_alu IS&lt;br /&gt;
PORT (&lt;br /&gt;
  clk         : IN  std_logic;&lt;br /&gt;
  rst         : IN  std_logic;&lt;br /&gt;
  enable_in   : IN  std_logic;&lt;br /&gt;
  start       : IN  std_logic;&lt;br /&gt;
  enable      : IN  std_logic;&lt;br /&gt;
  do_add      : IN  std_logic;&lt;br /&gt;
  do_subtract : IN  std_logic;&lt;br /&gt;
  do_hold     : IN  std_logic;&lt;br /&gt;
  data_in     : IN  std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  data_out    : OUT std_logic_vector(3 DOWNTO 0) BUS);&lt;br /&gt;
END add_sub_alu;&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE algorithm OF add_sub_alu IS&lt;br /&gt;
  TYPE   states          IS (hold, reset, add, subtract);&lt;br /&gt;
  SIGNAL state_var       : states;&lt;br /&gt;
  SIGNAL reg, int_reg    : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  SIGNAL latched_data_in : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
BEGIN&lt;br /&gt;
&lt;br /&gt;
latch: PROCESS (enable_in, data_in)is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (enable_in = &#039;1&#039;) THEN&lt;br /&gt;
    latched_data_in &amp;lt;= data_in;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS latch;&lt;br /&gt;
&lt;br /&gt;
fsm: PROCESS (clk, rst) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (rst = &#039;0&#039;) THEN&lt;br /&gt;
    state_var &amp;lt;= reset;&lt;br /&gt;
  ELSIF rising_edge(clk) THEN&lt;br /&gt;
    CASE state_var IS&lt;br /&gt;
      WHEN hold =&amp;gt;&lt;br /&gt;
        IF (start = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= reset;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN reset    =&amp;gt;&lt;br /&gt;
        IF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN add      =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN subtract =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN OTHERS =&amp;gt; state_var &amp;lt;= reset;&lt;br /&gt;
    END CASE;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS fsm;&lt;br /&gt;
&lt;br /&gt;
alu: PROCESS (state_var, latched_data_in, reg)is&lt;br /&gt;
BEGIN&lt;br /&gt;
CASE state_var IS&lt;br /&gt;
  WHEN add      =&amp;gt; int_reg &amp;lt;= reg + latched_data_in;&lt;br /&gt;
  WHEN subtract =&amp;gt; int_reg &amp;lt;= reg - latched_data_in;&lt;br /&gt;
  WHEN reset    =&amp;gt; int_reg &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
  WHEN hold     =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
  WHEN OTHERS   =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
END CASE;&lt;br /&gt;
END PROCESS alu;&lt;br /&gt;
&lt;br /&gt;
mem: PROCESS (clk) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF rising_edge(clk) THEN&lt;br /&gt;
    reg &amp;lt;= int_reg;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS mem;&lt;br /&gt;
&lt;br /&gt;
tri: PROCESS (enable, reg) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  FOR i IN 3 DOWNTO 0 LOOP&lt;br /&gt;
    IF (enable = &#039;1&#039;) THEN&lt;br /&gt;
      data_out(i) &amp;lt;= reg(i);&lt;br /&gt;
    ELSE&lt;br /&gt;
      data_out(i) &amp;lt;= &#039;Z&#039;;&lt;br /&gt;
    END IF;&lt;br /&gt;
  END LOOP;&lt;br /&gt;
END PROCESS tri;&lt;br /&gt;
&lt;br /&gt;
END algorithm;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Koden til alu_tb.vhdl===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library ieee;&lt;br /&gt;
use ieee.std_logic_1164.all;&lt;br /&gt;
library work;&lt;br /&gt;
use work.all;&lt;br /&gt;
&lt;br /&gt;
entity alu_tb is&lt;br /&gt;
end entity alu_tb;&lt;br /&gt;
&lt;br /&gt;
architecture struct of alu_tb is&lt;br /&gt;
--Deklaring av signal som skal koblast til komponentane.&lt;br /&gt;
--Alle innsignal er felles, medan vi har 2 forskjellige utsignal.&lt;br /&gt;
signal clk, reset : std_logic;&lt;br /&gt;
signal enable_in : std_logic;&lt;br /&gt;
signal start : std_logic;&lt;br /&gt;
signal enable : std_logic;&lt;br /&gt;
signal do_add : std_logic;&lt;br /&gt;
signal do_subtract : std_logic;&lt;br /&gt;
signal do_hold : std_logic;&lt;br /&gt;
signal data_in : std_logic_vector(3 downto 0);&lt;br /&gt;
signal data_out : std_logic_vector(3 downto 0);&lt;br /&gt;
signal data_out_synt : std_logic_vector(3 downto 0);&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
--Deklarer komponenten alu.&lt;br /&gt;
alu : entity add_sub_alu(algorithm)&lt;br /&gt;
&lt;br /&gt;
--Kobler signala til den opprinnelige komponenten.&lt;br /&gt;
port map (&lt;br /&gt;
clk =&amp;gt; clk,&lt;br /&gt;
rst =&amp;gt; reset,&lt;br /&gt;
enable_in =&amp;gt; enable_in,&lt;br /&gt;
start =&amp;gt; start,&lt;br /&gt;
enable =&amp;gt; enable,&lt;br /&gt;
do_add =&amp;gt; do_add,&lt;br /&gt;
do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
do_hold =&amp;gt; do_hold,&lt;br /&gt;
data_in =&amp;gt; data_in,&lt;br /&gt;
data_out =&amp;gt; data_out);&lt;br /&gt;
&lt;br /&gt;
--Deklarer komponenten alu_synt.&lt;br /&gt;
alu_synt : entity add_sub_alu_synth(structure)&lt;br /&gt;
&lt;br /&gt;
--Kobler signala til den synthiserte komponenten.&lt;br /&gt;
port map (&lt;br /&gt;
clk =&amp;gt; clk,&lt;br /&gt;
rst =&amp;gt; reset,&lt;br /&gt;
enable_in =&amp;gt; enable_in,&lt;br /&gt;
start =&amp;gt; start,&lt;br /&gt;
enable =&amp;gt; enable,&lt;br /&gt;
do_add =&amp;gt; do_add,&lt;br /&gt;
do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
do_hold =&amp;gt; do_hold,&lt;br /&gt;
data_in =&amp;gt; data_in,&lt;br /&gt;
data_out =&amp;gt; data_out_synt);&lt;br /&gt;
&lt;br /&gt;
--Klokkegenerator&lt;br /&gt;
clock_gen : process&lt;br /&gt;
begin&lt;br /&gt;
clk &amp;lt;= &#039;0&#039;, &#039;1&#039; after 50 ns;&lt;br /&gt;
wait for 100 ns;&lt;br /&gt;
end process clock_gen;&lt;br /&gt;
&lt;br /&gt;
--Setter testvektorane.&lt;br /&gt;
reset &amp;lt;= &#039;0&#039;, &#039;1&#039; after 60 ns;&lt;br /&gt;
enable &amp;lt;= &#039;1&#039;, &#039;0&#039; after 900 ns;&lt;br /&gt;
enable_in &amp;lt;= &#039;1&#039;, &#039;0&#039; after 400 ns;&lt;br /&gt;
start &amp;lt;= &#039;1&#039;, &#039;0&#039; after 300 ns;&lt;br /&gt;
do_add &amp;lt;= &#039;1&#039;, &#039;0&#039; after 660 ns;&lt;br /&gt;
do_subtract &amp;lt;= &#039;0&#039;;&lt;br /&gt;
do_hold &amp;lt;= &#039;0&#039;;&lt;br /&gt;
data_in &amp;lt;= X&amp;quot;3&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
--Test process for å samanlikne utsignala kvart nanosekund.&lt;br /&gt;
test : process&lt;br /&gt;
begin&lt;br /&gt;
wait for 1 ns;&lt;br /&gt;
assert (data_out = data_out_synt)&lt;br /&gt;
report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
severity Error;&lt;br /&gt;
end process test;&lt;br /&gt;
&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2808</id>
		<title>Synthese av VHDL</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2808"/>
		<updated>2021-02-04T13:39:37Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Syntetiseringen av VHDL kode===&lt;br /&gt;
&lt;br /&gt;
Grunnen til at vi skal syntetisere koden, er at vi må lage beskrivelse av koden tilpassa ein krets.&lt;br /&gt;
&lt;br /&gt;
Vi vil no prøve å synthesisere vhdl kode. Og etterpå vil vi lage ein testbenk der vi samanliknar utsignala frå den syntetiserte og den opprinnelige koden. Vi bruker ein alu som eksempel.&lt;br /&gt;
&lt;br /&gt;
==Precision==&lt;br /&gt;
&lt;br /&gt;
Precision bruker Vivado til å syntetisere vhdl-koden. For å starte synteseprogrammet:&lt;br /&gt;
&lt;br /&gt;
 export LM_LICENSE_FILE=1717@lisensserver;2100@lisensserver&lt;br /&gt;
 source /eda/mentor/2019-20/scripts/PRECISION_2019.1.1_RHELx86.sh&lt;br /&gt;
 precision&lt;br /&gt;
&lt;br /&gt;
Pass på at Precision finner Vivado, settes i menyen:&lt;br /&gt;
 Tools &amp;gt; Options &amp;gt; Place and Route Settings&lt;br /&gt;
deretter&lt;br /&gt;
 Vivado &amp;gt; Integrated Place and Route &amp;gt; path to Xilinx Vivado installation tree&lt;br /&gt;
settes til&lt;br /&gt;
 /eda/xilinx/Vivado/2020.2&lt;br /&gt;
&lt;br /&gt;
Vel deretter New Project, og deretter Add input file(i dette tilfelle add_sub_alu.vhd).&lt;br /&gt;
Så går vi inn på Setup design, velger ein kretsprodusent, den ønska kretsen og designfrekvens, for eksempel Zynq med frekvens 200MHz. For å få ut en vhdl fil av den syntetiserte koden må en gå på Tools-&amp;gt;Options-&amp;gt;Output og hak av for VHDL og trykk ok.&lt;br /&gt;
Trykk så compile, og synthesize. &lt;br /&gt;
No kan vi sjå på den generte kretsen i RTL Schematic og Technology Schematic(syntese med den valgte kretsen) under Schematics på venstre side.&lt;br /&gt;
&lt;br /&gt;
==Questasim==&lt;br /&gt;
&lt;br /&gt;
Start opp Questasim, lag nytt prosjekt og legg til vhdl fila(add_sub_alu.vhdl). Så legg vi til fila som Precision generte i prosjektdir til &#039;precision/prosjektnavn_temp_1/prosjektnavn.vhd&#039; (i vårt tilfelle &#039;alu/add_sub_alu_temp_1/add_sub_alu.vhd&#039;).&lt;br /&gt;
&lt;br /&gt;
Vi trenger simuleringsbibliotek for den valgte kretsfamilien for å kunne simulere etter &amp;quot;Place and Route&amp;quot;. Disse bibliotekene kan genereres fra Vivado med menyen&lt;br /&gt;
 Tools &amp;gt; Compile Simulation Libraries&lt;br /&gt;
men, vi har kompilert disse unisim-bibliotekene til mappen /eda/xilinx/lib. Du kan &amp;quot;mappe&amp;quot; disse slik:&lt;br /&gt;
&lt;br /&gt;
 vmap unisim /eda/xilinx/lib/unisim&lt;br /&gt;
 &lt;br /&gt;
Deretter legger vi til ei ny vhdl fil der vi skal lage testbenken vår. Vi legger til ein komponent av den opprinnelige og den synthesiserte vhdl koden. Vi koblar alle inngangane til samme signal på testbenken, og gir ut 2 forskjellige utsignal for å samanlikne ved hjelp av assert(sjå fila alu_tb.vhdl). På grunn av at utsignala av dei to komponentane ikkje skifta heilt synkront, testa vi berre kvart nanosekund ved å putta assert inn i ein process med wait for 1ns:&lt;br /&gt;
&lt;br /&gt;
 test : process&lt;br /&gt;
 begin&lt;br /&gt;
 wait for 1 ns;&lt;br /&gt;
 assert (data_out = data_out_synt)&lt;br /&gt;
 report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
 severity Error;&lt;br /&gt;
 end process test;&lt;br /&gt;
&lt;br /&gt;
Når vi har laga testbenken, kompilerer vi filene (husk å kompilere i rett rekkefølge med compileorder-&amp;gt;autogenerate første gong).&lt;br /&gt;
&lt;br /&gt;
Siden precision generer samme navn på entityen og architecturen på den syntetiserte filen som i den orginale så vil ikke simulatoren kjøre de samtidig. Dette endres ved å endre entity fra add_sub_alu til add_sub_alu_synth og skifte navnet på architecture fra algoritm til structure øverst og nederst i den syntetiserte filen.&lt;br /&gt;
&lt;br /&gt;
==Simulering med timing==&lt;br /&gt;
&lt;br /&gt;
Eksempel på start av simulering med timing:&lt;br /&gt;
&lt;br /&gt;
 vsim -t ps alu_tb -sdfmax :alu_tb:ali=/heim/yngve/vhdl/syntese/alu_temp_1/simulation/modelsim/add_sub_alu_vhd.sdo&lt;br /&gt;
&lt;br /&gt;
Vi kan sjå at i dei første 50 nanosekunda er utsignala ulike. Dette er fordi før første klokkeflanke er verdiane udefinert i den opprinnelige komponenten, medan den synthesisere ikkje kan ha udefinerte verdiar. I Modelsim vil vi derfor få ein del feilmeldingar dei første 50 nanosekunda.&lt;br /&gt;
&lt;br /&gt;
==Konklusjon==&lt;br /&gt;
&lt;br /&gt;
Vi kan teste om den synthesisere komponenten oppfører seg likt med den opprinnelige komponenten ved å koble begge to til samme testbenk. Vi fekk problem i overgangane når vi testa kontinuerlig, så vi løyste problemet ved å berre teste kvart naonosekund. Bortsett frå dei første 50 nanosekunda(sjå grunn over) kan vi sjå at begge komponetane gir ut samme utsignal. Vi prøvde å bruke samme enitynavn på begge komponentane med ulik arcitechture, men fekk berre lov å kompilere og ikkje simulere. Vi kan derfor konkludere med at desse må ha ulike navn.&lt;br /&gt;
&lt;br /&gt;
==Kode==&lt;br /&gt;
&lt;br /&gt;
===Kode til add_sub_alu.vhd===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.All;&lt;br /&gt;
USE ieee.std_logic_unsigned.all;&lt;br /&gt;
&lt;br /&gt;
ENTITY add_sub_alu IS&lt;br /&gt;
PORT (&lt;br /&gt;
  clk         : IN  std_logic;&lt;br /&gt;
  rst         : IN  std_logic;&lt;br /&gt;
  enable_in   : IN  std_logic;&lt;br /&gt;
  start       : IN  std_logic;&lt;br /&gt;
  enable      : IN  std_logic;&lt;br /&gt;
  do_add      : IN  std_logic;&lt;br /&gt;
  do_subtract : IN  std_logic;&lt;br /&gt;
  do_hold     : IN  std_logic;&lt;br /&gt;
  data_in     : IN  std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  data_out    : OUT std_logic_vector(3 DOWNTO 0) BUS);&lt;br /&gt;
END add_sub_alu;&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE algorithm OF add_sub_alu IS&lt;br /&gt;
  TYPE   states          IS (hold, reset, add, subtract);&lt;br /&gt;
  SIGNAL state_var       : states;&lt;br /&gt;
  SIGNAL reg, int_reg    : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  SIGNAL latched_data_in : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
BEGIN&lt;br /&gt;
&lt;br /&gt;
latch: PROCESS (enable_in, data_in)is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (enable_in = &#039;1&#039;) THEN&lt;br /&gt;
    latched_data_in &amp;lt;= data_in;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS latch;&lt;br /&gt;
&lt;br /&gt;
fsm: PROCESS (clk, rst) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (rst = &#039;0&#039;) THEN&lt;br /&gt;
    state_var &amp;lt;= reset;&lt;br /&gt;
  ELSIF rising_edge(clk) THEN&lt;br /&gt;
    CASE state_var IS&lt;br /&gt;
      WHEN hold =&amp;gt;&lt;br /&gt;
        IF (start = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= reset;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN reset    =&amp;gt;&lt;br /&gt;
        IF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN add      =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN subtract =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN OTHERS =&amp;gt; state_var &amp;lt;= reset;&lt;br /&gt;
    END CASE;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS fsm;&lt;br /&gt;
&lt;br /&gt;
alu: PROCESS (state_var, latched_data_in, reg)is&lt;br /&gt;
BEGIN&lt;br /&gt;
CASE state_var IS&lt;br /&gt;
  WHEN add      =&amp;gt; int_reg &amp;lt;= reg + latched_data_in;&lt;br /&gt;
  WHEN subtract =&amp;gt; int_reg &amp;lt;= reg - latched_data_in;&lt;br /&gt;
  WHEN reset    =&amp;gt; int_reg &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
  WHEN hold     =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
  WHEN OTHERS   =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
END CASE;&lt;br /&gt;
END PROCESS alu;&lt;br /&gt;
&lt;br /&gt;
mem: PROCESS (clk) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF rising_edge(clk) THEN&lt;br /&gt;
    reg &amp;lt;= int_reg;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS mem;&lt;br /&gt;
&lt;br /&gt;
tri: PROCESS (enable, reg) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  FOR i IN 3 DOWNTO 0 LOOP&lt;br /&gt;
    IF (enable = &#039;1&#039;) THEN&lt;br /&gt;
      data_out(i) &amp;lt;= reg(i);&lt;br /&gt;
    ELSE&lt;br /&gt;
      data_out(i) &amp;lt;= &#039;Z&#039;;&lt;br /&gt;
    END IF;&lt;br /&gt;
  END LOOP;&lt;br /&gt;
END PROCESS tri;&lt;br /&gt;
&lt;br /&gt;
END algorithm;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Koden til alu_tb.vhdl===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library ieee;&lt;br /&gt;
use ieee.std_logic_1164.all;&lt;br /&gt;
library work;&lt;br /&gt;
use work.all;&lt;br /&gt;
&lt;br /&gt;
entity alu_tb is&lt;br /&gt;
end entity alu_tb;&lt;br /&gt;
&lt;br /&gt;
architecture struct of alu_tb is&lt;br /&gt;
--Deklaring av signal som skal koblast til komponentane.&lt;br /&gt;
--Alle innsignal er felles, medan vi har 2 forskjellige utsignal.&lt;br /&gt;
signal clk, reset : std_logic;&lt;br /&gt;
signal enable_in : std_logic;&lt;br /&gt;
signal start : std_logic;&lt;br /&gt;
signal enable : std_logic;&lt;br /&gt;
signal do_add : std_logic;&lt;br /&gt;
signal do_subtract : std_logic;&lt;br /&gt;
signal do_hold : std_logic;&lt;br /&gt;
signal data_in : std_logic_vector(3 downto 0);&lt;br /&gt;
signal data_out : std_logic_vector(3 downto 0);&lt;br /&gt;
signal data_out_synt : std_logic_vector(3 downto 0);&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
--Deklarer komponenten alu.&lt;br /&gt;
alu : entity add_sub_alu(algorithm)&lt;br /&gt;
&lt;br /&gt;
--Kobler signala til den opprinnelige komponenten.&lt;br /&gt;
port map (&lt;br /&gt;
clk =&amp;gt; clk,&lt;br /&gt;
rst =&amp;gt; reset,&lt;br /&gt;
enable_in =&amp;gt; enable_in,&lt;br /&gt;
start =&amp;gt; start,&lt;br /&gt;
enable =&amp;gt; enable,&lt;br /&gt;
do_add =&amp;gt; do_add,&lt;br /&gt;
do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
do_hold =&amp;gt; do_hold,&lt;br /&gt;
data_in =&amp;gt; data_in,&lt;br /&gt;
data_out =&amp;gt; data_out);&lt;br /&gt;
&lt;br /&gt;
--Deklarer komponenten alu_synt.&lt;br /&gt;
alu_synt : entity add_sub_alu_synth(structure)&lt;br /&gt;
&lt;br /&gt;
--Kobler signala til den synthiserte komponenten.&lt;br /&gt;
port map (&lt;br /&gt;
clk =&amp;gt; clk,&lt;br /&gt;
rst =&amp;gt; reset,&lt;br /&gt;
enable_in =&amp;gt; enable_in,&lt;br /&gt;
start =&amp;gt; start,&lt;br /&gt;
enable =&amp;gt; enable,&lt;br /&gt;
do_add =&amp;gt; do_add,&lt;br /&gt;
do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
do_hold =&amp;gt; do_hold,&lt;br /&gt;
data_in =&amp;gt; data_in,&lt;br /&gt;
data_out =&amp;gt; data_out_synt);&lt;br /&gt;
&lt;br /&gt;
--Klokkegenerator&lt;br /&gt;
clock_gen : process&lt;br /&gt;
begin&lt;br /&gt;
clk &amp;lt;= &#039;0&#039;, &#039;1&#039; after 50 ns;&lt;br /&gt;
wait for 100 ns;&lt;br /&gt;
end process clock_gen;&lt;br /&gt;
&lt;br /&gt;
--Setter testvektorane.&lt;br /&gt;
reset &amp;lt;= &#039;0&#039;, &#039;1&#039; after 60 ns;&lt;br /&gt;
enable &amp;lt;= &#039;1&#039;, &#039;0&#039; after 900 ns;&lt;br /&gt;
enable_in &amp;lt;= &#039;1&#039;, &#039;0&#039; after 400 ns;&lt;br /&gt;
start &amp;lt;= &#039;1&#039;, &#039;0&#039; after 300 ns;&lt;br /&gt;
do_add &amp;lt;= &#039;1&#039;, &#039;0&#039; after 660 ns;&lt;br /&gt;
do_subtract &amp;lt;= &#039;0&#039;;&lt;br /&gt;
do_hold &amp;lt;= &#039;0&#039;;&lt;br /&gt;
data_in &amp;lt;= X&amp;quot;3&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
--Test process for å samanlikne utsignala kvart nanosekund.&lt;br /&gt;
test : process&lt;br /&gt;
begin&lt;br /&gt;
wait for 1 ns;&lt;br /&gt;
assert (data_out = data_out_synt)&lt;br /&gt;
report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
severity Error;&lt;br /&gt;
end process test;&lt;br /&gt;
&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2807</id>
		<title>Synthese av VHDL</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2807"/>
		<updated>2021-02-04T13:37:06Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Syntetiseringen av VHDL kode===&lt;br /&gt;
&lt;br /&gt;
Grunnen til at vi skal syntetisere koden, er at vi må lage beskrivelse av koden tilpassa ein krets.&lt;br /&gt;
&lt;br /&gt;
Vi vil no prøve å synthesisere vhdl kode. Og etterpå vil vi lage ein testbenk der vi samanliknar utsignala frå den syntetiserte og den opprinnelige koden. Vi bruker ein alu som eksempel.&lt;br /&gt;
&lt;br /&gt;
==Precision==&lt;br /&gt;
&lt;br /&gt;
Precision bruker Vivado til å syntetisere vhdl-koden. For å starte synteseprogrammet:&lt;br /&gt;
&lt;br /&gt;
 export LM_LICENSE_FILE=1717@lisensserver;2100@lisensserver&lt;br /&gt;
 source /eda/mentor/2019-20/scripts/PRECISION_2019.1.1_RHELx86.sh&lt;br /&gt;
 precision&lt;br /&gt;
&lt;br /&gt;
Pass på at Precision finner Vivado, settes i menyen:&lt;br /&gt;
 Tools &amp;gt; Options &amp;gt; Place and Route Settings&lt;br /&gt;
deretter&lt;br /&gt;
 Vivado &amp;gt; Integrated Place and Route &amp;gt; path to Xilinx Vivado installation tree&lt;br /&gt;
settes til&lt;br /&gt;
 /eda/xilinx/Vivado/2020.2&lt;br /&gt;
&lt;br /&gt;
Vel deretter New Project, og deretter Add input file(i dette tilfelle add_sub_alu.vhd).&lt;br /&gt;
Så går vi inn på Setup design, velger ein kretsprodusent, den ønska kretsen og designfrekvens, for eksempel Zynq med frekvens 200MHz. For å få ut en vhdl fil av den syntetiserte koden må en gå på Tools-&amp;gt;Options-&amp;gt;Output og hak av for VHDL og trykk ok.&lt;br /&gt;
Trykk så compile, og synthesize. &lt;br /&gt;
No kan vi sjå på den generte kretsen i RTL Schematic og Technology Schematic(syntese med den valgte kretsen) under Schematics på venstre side.&lt;br /&gt;
&lt;br /&gt;
==Questasim==&lt;br /&gt;
&lt;br /&gt;
Start opp Questasim, lag nytt prosjekt og legg til vhdl fila(add_sub_alu.vhdl). Så legg vi til fila som Precision generte i prosjektdir til &#039;precision/prosjektnavn_temp_1/prosjektnavn.vhd&#039; (i vårt tilfelle &#039;alu/add_sub_alu_temp_1/add_sub_alu.vhd&#039;).&lt;br /&gt;
&lt;br /&gt;
Vi trenger simuleringsbibliotek for den valgte kretsfamilien for å kunne simulere etter &amp;quot;Place and Route&amp;quot;. Disse bibliotekene kan genereres fra Quartus med menyen Tools &amp;gt; Launch EDA Simulation Simulation Library Compiler.&lt;br /&gt;
&lt;br /&gt;
Vi har kompilert disse bibliotekene til mappen /eda/xilinx. Du kan &amp;quot;mappe&amp;quot; disse for eksempel slik:&lt;br /&gt;
&lt;br /&gt;
 vmap unisim /eda/xilinx/lib/unisim&lt;br /&gt;
 &lt;br /&gt;
Deretter legger vi til ei ny vhdl fil der vi skal lage testbenken vår. Vi legger til ein komponent av den opprinnelige og den synthesiserte vhdl koden. Vi koblar alle inngangane til samme signal på testbenken, og gir ut 2 forskjellige utsignal for å samanlikne ved hjelp av assert(sjå fila alu_tb.vhdl). På grunn av at utsignala av dei to komponentane ikkje skifta heilt synkront, testa vi berre kvart nanosekund ved å putta assert inn i ein process med wait for 1ns:&lt;br /&gt;
&lt;br /&gt;
 test : process&lt;br /&gt;
 begin&lt;br /&gt;
 wait for 1 ns;&lt;br /&gt;
 assert (data_out = data_out_synt)&lt;br /&gt;
 report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
 severity Error;&lt;br /&gt;
 end process test;&lt;br /&gt;
&lt;br /&gt;
Når vi har laga testbenken, kompilerer vi filene (husk å kompilere i rett rekkefølge med compileorder-&amp;gt;autogenerate første gong).&lt;br /&gt;
&lt;br /&gt;
Siden precision generer samme navn på entityen og architecturen på den syntetiserte filen som i den orginale så vil ikke simulatoren kjøre de samtidig. Dette endres ved å endre entity fra add_sub_alu til add_sub_alu_synth og skifte navnet på architecture fra algoritm til structure øverst og nederst i den syntetiserte filen.&lt;br /&gt;
&lt;br /&gt;
==Simulering med timing==&lt;br /&gt;
&lt;br /&gt;
Eksempel på start av simulering med timing:&lt;br /&gt;
&lt;br /&gt;
 vsim -t ps alu_tb -sdfmax :alu_tb:ali=/heim/yngve/vhdl/syntese/alu_temp_1/simulation/modelsim/add_sub_alu_vhd.sdo&lt;br /&gt;
&lt;br /&gt;
Vi kan sjå at i dei første 50 nanosekunda er utsignala ulike. Dette er fordi før første klokkeflanke er verdiane udefinert i den opprinnelige komponenten, medan den synthesisere ikkje kan ha udefinerte verdiar. I Modelsim vil vi derfor få ein del feilmeldingar dei første 50 nanosekunda.&lt;br /&gt;
&lt;br /&gt;
==Konklusjon==&lt;br /&gt;
&lt;br /&gt;
Vi kan teste om den synthesisere komponenten oppfører seg likt med den opprinnelige komponenten ved å koble begge to til samme testbenk. Vi fekk problem i overgangane når vi testa kontinuerlig, så vi løyste problemet ved å berre teste kvart naonosekund. Bortsett frå dei første 50 nanosekunda(sjå grunn over) kan vi sjå at begge komponetane gir ut samme utsignal. Vi prøvde å bruke samme enitynavn på begge komponentane med ulik arcitechture, men fekk berre lov å kompilere og ikkje simulere. Vi kan derfor konkludere med at desse må ha ulike navn.&lt;br /&gt;
&lt;br /&gt;
==Kode==&lt;br /&gt;
&lt;br /&gt;
===Kode til add_sub_alu.vhd===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.All;&lt;br /&gt;
USE ieee.std_logic_unsigned.all;&lt;br /&gt;
&lt;br /&gt;
ENTITY add_sub_alu IS&lt;br /&gt;
PORT (&lt;br /&gt;
  clk         : IN  std_logic;&lt;br /&gt;
  rst         : IN  std_logic;&lt;br /&gt;
  enable_in   : IN  std_logic;&lt;br /&gt;
  start       : IN  std_logic;&lt;br /&gt;
  enable      : IN  std_logic;&lt;br /&gt;
  do_add      : IN  std_logic;&lt;br /&gt;
  do_subtract : IN  std_logic;&lt;br /&gt;
  do_hold     : IN  std_logic;&lt;br /&gt;
  data_in     : IN  std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  data_out    : OUT std_logic_vector(3 DOWNTO 0) BUS);&lt;br /&gt;
END add_sub_alu;&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE algorithm OF add_sub_alu IS&lt;br /&gt;
  TYPE   states          IS (hold, reset, add, subtract);&lt;br /&gt;
  SIGNAL state_var       : states;&lt;br /&gt;
  SIGNAL reg, int_reg    : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  SIGNAL latched_data_in : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
BEGIN&lt;br /&gt;
&lt;br /&gt;
latch: PROCESS (enable_in, data_in)is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (enable_in = &#039;1&#039;) THEN&lt;br /&gt;
    latched_data_in &amp;lt;= data_in;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS latch;&lt;br /&gt;
&lt;br /&gt;
fsm: PROCESS (clk, rst) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (rst = &#039;0&#039;) THEN&lt;br /&gt;
    state_var &amp;lt;= reset;&lt;br /&gt;
  ELSIF rising_edge(clk) THEN&lt;br /&gt;
    CASE state_var IS&lt;br /&gt;
      WHEN hold =&amp;gt;&lt;br /&gt;
        IF (start = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= reset;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN reset    =&amp;gt;&lt;br /&gt;
        IF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN add      =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN subtract =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN OTHERS =&amp;gt; state_var &amp;lt;= reset;&lt;br /&gt;
    END CASE;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS fsm;&lt;br /&gt;
&lt;br /&gt;
alu: PROCESS (state_var, latched_data_in, reg)is&lt;br /&gt;
BEGIN&lt;br /&gt;
CASE state_var IS&lt;br /&gt;
  WHEN add      =&amp;gt; int_reg &amp;lt;= reg + latched_data_in;&lt;br /&gt;
  WHEN subtract =&amp;gt; int_reg &amp;lt;= reg - latched_data_in;&lt;br /&gt;
  WHEN reset    =&amp;gt; int_reg &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
  WHEN hold     =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
  WHEN OTHERS   =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
END CASE;&lt;br /&gt;
END PROCESS alu;&lt;br /&gt;
&lt;br /&gt;
mem: PROCESS (clk) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF rising_edge(clk) THEN&lt;br /&gt;
    reg &amp;lt;= int_reg;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS mem;&lt;br /&gt;
&lt;br /&gt;
tri: PROCESS (enable, reg) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  FOR i IN 3 DOWNTO 0 LOOP&lt;br /&gt;
    IF (enable = &#039;1&#039;) THEN&lt;br /&gt;
      data_out(i) &amp;lt;= reg(i);&lt;br /&gt;
    ELSE&lt;br /&gt;
      data_out(i) &amp;lt;= &#039;Z&#039;;&lt;br /&gt;
    END IF;&lt;br /&gt;
  END LOOP;&lt;br /&gt;
END PROCESS tri;&lt;br /&gt;
&lt;br /&gt;
END algorithm;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Koden til alu_tb.vhdl===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library ieee;&lt;br /&gt;
use ieee.std_logic_1164.all;&lt;br /&gt;
library work;&lt;br /&gt;
use work.all;&lt;br /&gt;
&lt;br /&gt;
entity alu_tb is&lt;br /&gt;
end entity alu_tb;&lt;br /&gt;
&lt;br /&gt;
architecture struct of alu_tb is&lt;br /&gt;
--Deklaring av signal som skal koblast til komponentane.&lt;br /&gt;
--Alle innsignal er felles, medan vi har 2 forskjellige utsignal.&lt;br /&gt;
signal clk, reset : std_logic;&lt;br /&gt;
signal enable_in : std_logic;&lt;br /&gt;
signal start : std_logic;&lt;br /&gt;
signal enable : std_logic;&lt;br /&gt;
signal do_add : std_logic;&lt;br /&gt;
signal do_subtract : std_logic;&lt;br /&gt;
signal do_hold : std_logic;&lt;br /&gt;
signal data_in : std_logic_vector(3 downto 0);&lt;br /&gt;
signal data_out : std_logic_vector(3 downto 0);&lt;br /&gt;
signal data_out_synt : std_logic_vector(3 downto 0);&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
--Deklarer komponenten alu.&lt;br /&gt;
alu : entity add_sub_alu(algorithm)&lt;br /&gt;
&lt;br /&gt;
--Kobler signala til den opprinnelige komponenten.&lt;br /&gt;
port map (&lt;br /&gt;
clk =&amp;gt; clk,&lt;br /&gt;
rst =&amp;gt; reset,&lt;br /&gt;
enable_in =&amp;gt; enable_in,&lt;br /&gt;
start =&amp;gt; start,&lt;br /&gt;
enable =&amp;gt; enable,&lt;br /&gt;
do_add =&amp;gt; do_add,&lt;br /&gt;
do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
do_hold =&amp;gt; do_hold,&lt;br /&gt;
data_in =&amp;gt; data_in,&lt;br /&gt;
data_out =&amp;gt; data_out);&lt;br /&gt;
&lt;br /&gt;
--Deklarer komponenten alu_synt.&lt;br /&gt;
alu_synt : entity add_sub_alu_synth(structure)&lt;br /&gt;
&lt;br /&gt;
--Kobler signala til den synthiserte komponenten.&lt;br /&gt;
port map (&lt;br /&gt;
clk =&amp;gt; clk,&lt;br /&gt;
rst =&amp;gt; reset,&lt;br /&gt;
enable_in =&amp;gt; enable_in,&lt;br /&gt;
start =&amp;gt; start,&lt;br /&gt;
enable =&amp;gt; enable,&lt;br /&gt;
do_add =&amp;gt; do_add,&lt;br /&gt;
do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
do_hold =&amp;gt; do_hold,&lt;br /&gt;
data_in =&amp;gt; data_in,&lt;br /&gt;
data_out =&amp;gt; data_out_synt);&lt;br /&gt;
&lt;br /&gt;
--Klokkegenerator&lt;br /&gt;
clock_gen : process&lt;br /&gt;
begin&lt;br /&gt;
clk &amp;lt;= &#039;0&#039;, &#039;1&#039; after 50 ns;&lt;br /&gt;
wait for 100 ns;&lt;br /&gt;
end process clock_gen;&lt;br /&gt;
&lt;br /&gt;
--Setter testvektorane.&lt;br /&gt;
reset &amp;lt;= &#039;0&#039;, &#039;1&#039; after 60 ns;&lt;br /&gt;
enable &amp;lt;= &#039;1&#039;, &#039;0&#039; after 900 ns;&lt;br /&gt;
enable_in &amp;lt;= &#039;1&#039;, &#039;0&#039; after 400 ns;&lt;br /&gt;
start &amp;lt;= &#039;1&#039;, &#039;0&#039; after 300 ns;&lt;br /&gt;
do_add &amp;lt;= &#039;1&#039;, &#039;0&#039; after 660 ns;&lt;br /&gt;
do_subtract &amp;lt;= &#039;0&#039;;&lt;br /&gt;
do_hold &amp;lt;= &#039;0&#039;;&lt;br /&gt;
data_in &amp;lt;= X&amp;quot;3&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
--Test process for å samanlikne utsignala kvart nanosekund.&lt;br /&gt;
test : process&lt;br /&gt;
begin&lt;br /&gt;
wait for 1 ns;&lt;br /&gt;
assert (data_out = data_out_synt)&lt;br /&gt;
report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
severity Error;&lt;br /&gt;
end process test;&lt;br /&gt;
&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2806</id>
		<title>Synthese av VHDL</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Synthese_av_VHDL&amp;diff=2806"/>
		<updated>2021-02-04T12:52:47Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: Updated to Vivado&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Syntetiseringen av VHDL kode===&lt;br /&gt;
&lt;br /&gt;
Grunnen til at vi skal syntetisere koden, er at vi må lage beskrivelse av koden tilpassa ein krets.&lt;br /&gt;
&lt;br /&gt;
Vi vil no prøve å synthesisere vhdl kode. Og etterpå vil vi lage ein testbenk der vi samanliknar utsignala frå den syntetiserte og den opprinnelige koden. Vi bruker ein alu som eksempel.&lt;br /&gt;
&lt;br /&gt;
==Precision==&lt;br /&gt;
&lt;br /&gt;
Precision bruker Vivado til å syntetisere vhdl-koden. For å starte synteseprogrammet:&lt;br /&gt;
&lt;br /&gt;
 export LM_LICENSE_FILE=1717@lisensserver;2100@lisensserver&lt;br /&gt;
 source /eda/mentor/2019-20/scripts/PRECISION_2019.1.1_RHELx86.sh&lt;br /&gt;
 precision&lt;br /&gt;
&lt;br /&gt;
Pass på at Precision finner Vivado, settes i menyen:&lt;br /&gt;
 Tools &amp;gt; Options &amp;gt; Place and Route Settings&lt;br /&gt;
deretter&lt;br /&gt;
 Vivado &amp;gt; Integrated Place and Route &amp;gt; path to Xilinx Vivado installation tree&lt;br /&gt;
settes til&lt;br /&gt;
 /eda/xilinx/Vivado/2020.2&lt;br /&gt;
&lt;br /&gt;
Vel deretter New Project, og deretter Add input file(i dette tilfelle add_sub_alu.vhd).&lt;br /&gt;
Så går vi inn på Setup design, velger ein kretsprodusent, den ønska kretsen og designfrekvens, for eksempel Zynq med frekvens 200MHz. For å få ut en vhdl fil av den syntetiserte koden må en gå på Tools-&amp;gt;Options-&amp;gt;Output og hak av for VHDL og trykk ok.&lt;br /&gt;
Trykk så compile, og synthesize. &lt;br /&gt;
No kan vi sjå på den generte kretsen i RTL Schematic og Technology Schematic(syntese med den valgte kretsen) under Schematics på venstre side.&lt;br /&gt;
&lt;br /&gt;
Hvis du får en &amp;quot;ROOTDIR&amp;quot;-error, mangler det en variabel. Skriv følgende i terminalen:&lt;br /&gt;
&lt;br /&gt;
 setenv QUARTUS_ROOTDIR /prog/altera/11.1/quartus&lt;br /&gt;
&lt;br /&gt;
==Modelsim==&lt;br /&gt;
&lt;br /&gt;
Start opp Modelsim, lag nytt prosjekt og legg til vhdl fila(add_sub_alu.vhdl). Så legg vi til fila som Precision generte i prosjektdir til &#039;precision/prosjektnavn_temp_1/prosjektnavn.vhd&#039; (i vårt tilfelle &#039;alu/add_sub_alu_temp_1/add_sub_alu.vhd&#039;).&lt;br /&gt;
&lt;br /&gt;
Vi trenger simuleringsbibliotek for den valgte kretsfamilien for å kunne simulere etter &amp;quot;Place and Route&amp;quot;. Disse bibliotekene kan genereres fra Quartus med menyen Tools &amp;gt; Launch EDA Simulation Simulation Library Compiler.&lt;br /&gt;
&lt;br /&gt;
Vi har kompilert disse bibliotekene til mappen /prog/altera/vhdl_libs. Du kan &amp;quot;mappe&amp;quot; disse for eksempel slik:&lt;br /&gt;
&lt;br /&gt;
 vmap cyclonev /eda/altera/17.0/quartus/eda/sim_lib&lt;br /&gt;
 &lt;br /&gt;
Deretter legger vi til ei ny vhdl fil der vi skal lage testbenken vår. Vi legger til ein komponent av den opprinnelige og den synthesiserte vhdl koden. Vi koblar alle inngangane til samme signal på testbenken, og gir ut 2 forskjellige utsignal for å samanlikne ved hjelp av assert(sjå fila alu_tb.vhdl). På grunn av at utsignala av dei to komponentane ikkje skifta heilt synkront, testa vi berre kvart nanosekund ved å putta assert inn i ein process med wait for 1ns:&lt;br /&gt;
&lt;br /&gt;
 test : process&lt;br /&gt;
 begin&lt;br /&gt;
 wait for 1 ns;&lt;br /&gt;
 assert (data_out = data_out_synt)&lt;br /&gt;
 report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
 severity Error;&lt;br /&gt;
 end process test;&lt;br /&gt;
&lt;br /&gt;
Når vi har laga testbenken, kompilerer vi filene (husk å kompilere i rett rekkefølge med compileorder-&amp;gt;autogenerate første gong).&lt;br /&gt;
&lt;br /&gt;
Siden precision generer samme navn på entityen og architecturen på den syntetiserte filen som i den orginale så vil ikke simulatoren kjøre de samtidig. Dette endres ved å endre entity fra add_sub_alu til add_sub_alu_synth og skifte navnet på architecture fra algoritm til structure øverst og nederst i den syntetiserte filen.&lt;br /&gt;
&lt;br /&gt;
==Simulering med timing==&lt;br /&gt;
&lt;br /&gt;
Eksemple på start av simulering med timing:&lt;br /&gt;
&lt;br /&gt;
 vsim -t ps alu_tb -sdfmax :alu_tb:ali=/heim/yngve/vhdl/syntese/alu_temp_1/simulation/modelsim/add_sub_alu_vhd.sdo&lt;br /&gt;
&lt;br /&gt;
Vi kan sjå at i dei første 50 nanosekunda er utsignala ulike. Dette er fordi før første klokkeflanke er verdiane udefinert i den opprinnelige komponenten, medan den synthesisere ikkje kan ha udefinerte verdiar. I Modelsim vil vi derfor få ein del feilmeldingar dei første 50 nanosekunda.&lt;br /&gt;
&lt;br /&gt;
==Konklusjon==&lt;br /&gt;
&lt;br /&gt;
Vi kan teste om den synthesisere komponenten oppfører seg likt med den opprinnelige komponenten ved å koble begge to til samme testbenk. Vi fekk problem i overgangane når vi testa kontinuerlig, så vi løyste problemet ved å berre teste kvart naonosekund. Bortsett frå dei første 50 nanosekunda(sjå grunn over) kan vi sjå at begge komponetane gir ut samme utsignal. Vi prøvde å bruke samme enitynavn på begge komponentane med ulik arcitechture, men fekk berre lov å kompilere og ikkje simulere. Vi kan derfor konkludere med at desse må ha ulike navn.&lt;br /&gt;
&lt;br /&gt;
==Kode==&lt;br /&gt;
&lt;br /&gt;
===Kode til add_sub_alu.vhd===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY ieee;&lt;br /&gt;
USE ieee.std_logic_1164.All;&lt;br /&gt;
USE ieee.std_logic_unsigned.all;&lt;br /&gt;
&lt;br /&gt;
ENTITY add_sub_alu IS&lt;br /&gt;
PORT (&lt;br /&gt;
  clk         : IN  std_logic;&lt;br /&gt;
  rst         : IN  std_logic;&lt;br /&gt;
  enable_in   : IN  std_logic;&lt;br /&gt;
  start       : IN  std_logic;&lt;br /&gt;
  enable      : IN  std_logic;&lt;br /&gt;
  do_add      : IN  std_logic;&lt;br /&gt;
  do_subtract : IN  std_logic;&lt;br /&gt;
  do_hold     : IN  std_logic;&lt;br /&gt;
  data_in     : IN  std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  data_out    : OUT std_logic_vector(3 DOWNTO 0) BUS);&lt;br /&gt;
END add_sub_alu;&lt;br /&gt;
&lt;br /&gt;
ARCHITECTURE algorithm OF add_sub_alu IS&lt;br /&gt;
  TYPE   states          IS (hold, reset, add, subtract);&lt;br /&gt;
  SIGNAL state_var       : states;&lt;br /&gt;
  SIGNAL reg, int_reg    : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
  SIGNAL latched_data_in : std_logic_vector(3 DOWNTO 0);&lt;br /&gt;
BEGIN&lt;br /&gt;
&lt;br /&gt;
latch: PROCESS (enable_in, data_in)is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (enable_in = &#039;1&#039;) THEN&lt;br /&gt;
    latched_data_in &amp;lt;= data_in;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS latch;&lt;br /&gt;
&lt;br /&gt;
fsm: PROCESS (clk, rst) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF (rst = &#039;0&#039;) THEN&lt;br /&gt;
    state_var &amp;lt;= reset;&lt;br /&gt;
  ELSIF rising_edge(clk) THEN&lt;br /&gt;
    CASE state_var IS&lt;br /&gt;
      WHEN hold =&amp;gt;&lt;br /&gt;
        IF (start = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= reset;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN reset    =&amp;gt;&lt;br /&gt;
        IF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN add      =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_subtract = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= subtract;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN subtract =&amp;gt;&lt;br /&gt;
        IF (do_hold = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= hold;&lt;br /&gt;
        ELSIF (do_add = &#039;1&#039;) THEN&lt;br /&gt;
          state_var &amp;lt;= add;&lt;br /&gt;
        END IF;&lt;br /&gt;
      WHEN OTHERS =&amp;gt; state_var &amp;lt;= reset;&lt;br /&gt;
    END CASE;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS fsm;&lt;br /&gt;
&lt;br /&gt;
alu: PROCESS (state_var, latched_data_in, reg)is&lt;br /&gt;
BEGIN&lt;br /&gt;
CASE state_var IS&lt;br /&gt;
  WHEN add      =&amp;gt; int_reg &amp;lt;= reg + latched_data_in;&lt;br /&gt;
  WHEN subtract =&amp;gt; int_reg &amp;lt;= reg - latched_data_in;&lt;br /&gt;
  WHEN reset    =&amp;gt; int_reg &amp;lt;= (others =&amp;gt; &#039;0&#039;);&lt;br /&gt;
  WHEN hold     =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
  WHEN OTHERS   =&amp;gt; int_reg &amp;lt;= reg;&lt;br /&gt;
END CASE;&lt;br /&gt;
END PROCESS alu;&lt;br /&gt;
&lt;br /&gt;
mem: PROCESS (clk) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  IF rising_edge(clk) THEN&lt;br /&gt;
    reg &amp;lt;= int_reg;&lt;br /&gt;
  END IF;&lt;br /&gt;
END PROCESS mem;&lt;br /&gt;
&lt;br /&gt;
tri: PROCESS (enable, reg) is&lt;br /&gt;
BEGIN&lt;br /&gt;
  FOR i IN 3 DOWNTO 0 LOOP&lt;br /&gt;
    IF (enable = &#039;1&#039;) THEN&lt;br /&gt;
      data_out(i) &amp;lt;= reg(i);&lt;br /&gt;
    ELSE&lt;br /&gt;
      data_out(i) &amp;lt;= &#039;Z&#039;;&lt;br /&gt;
    END IF;&lt;br /&gt;
  END LOOP;&lt;br /&gt;
END PROCESS tri;&lt;br /&gt;
&lt;br /&gt;
END algorithm;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Koden til alu_tb.vhdl===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library ieee;&lt;br /&gt;
use ieee.std_logic_1164.all;&lt;br /&gt;
library work;&lt;br /&gt;
use work.all;&lt;br /&gt;
&lt;br /&gt;
entity alu_tb is&lt;br /&gt;
end entity alu_tb;&lt;br /&gt;
&lt;br /&gt;
architecture struct of alu_tb is&lt;br /&gt;
--Deklaring av signal som skal koblast til komponentane.&lt;br /&gt;
--Alle innsignal er felles, medan vi har 2 forskjellige utsignal.&lt;br /&gt;
signal clk, reset : std_logic;&lt;br /&gt;
signal enable_in : std_logic;&lt;br /&gt;
signal start : std_logic;&lt;br /&gt;
signal enable : std_logic;&lt;br /&gt;
signal do_add : std_logic;&lt;br /&gt;
signal do_subtract : std_logic;&lt;br /&gt;
signal do_hold : std_logic;&lt;br /&gt;
signal data_in : std_logic_vector(3 downto 0);&lt;br /&gt;
signal data_out : std_logic_vector(3 downto 0);&lt;br /&gt;
signal data_out_synt : std_logic_vector(3 downto 0);&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
--Deklarer komponenten alu.&lt;br /&gt;
alu : entity add_sub_alu(algorithm)&lt;br /&gt;
&lt;br /&gt;
--Kobler signala til den opprinnelige komponenten.&lt;br /&gt;
port map (&lt;br /&gt;
clk =&amp;gt; clk,&lt;br /&gt;
rst =&amp;gt; reset,&lt;br /&gt;
enable_in =&amp;gt; enable_in,&lt;br /&gt;
start =&amp;gt; start,&lt;br /&gt;
enable =&amp;gt; enable,&lt;br /&gt;
do_add =&amp;gt; do_add,&lt;br /&gt;
do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
do_hold =&amp;gt; do_hold,&lt;br /&gt;
data_in =&amp;gt; data_in,&lt;br /&gt;
data_out =&amp;gt; data_out);&lt;br /&gt;
&lt;br /&gt;
--Deklarer komponenten alu_synt.&lt;br /&gt;
alu_synt : entity add_sub_alu_synth(structure)&lt;br /&gt;
&lt;br /&gt;
--Kobler signala til den synthiserte komponenten.&lt;br /&gt;
port map (&lt;br /&gt;
clk =&amp;gt; clk,&lt;br /&gt;
rst =&amp;gt; reset,&lt;br /&gt;
enable_in =&amp;gt; enable_in,&lt;br /&gt;
start =&amp;gt; start,&lt;br /&gt;
enable =&amp;gt; enable,&lt;br /&gt;
do_add =&amp;gt; do_add,&lt;br /&gt;
do_subtract =&amp;gt; do_subtract,&lt;br /&gt;
do_hold =&amp;gt; do_hold,&lt;br /&gt;
data_in =&amp;gt; data_in,&lt;br /&gt;
data_out =&amp;gt; data_out_synt);&lt;br /&gt;
&lt;br /&gt;
--Klokkegenerator&lt;br /&gt;
clock_gen : process&lt;br /&gt;
begin&lt;br /&gt;
clk &amp;lt;= &#039;0&#039;, &#039;1&#039; after 50 ns;&lt;br /&gt;
wait for 100 ns;&lt;br /&gt;
end process clock_gen;&lt;br /&gt;
&lt;br /&gt;
--Setter testvektorane.&lt;br /&gt;
reset &amp;lt;= &#039;0&#039;, &#039;1&#039; after 60 ns;&lt;br /&gt;
enable &amp;lt;= &#039;1&#039;, &#039;0&#039; after 900 ns;&lt;br /&gt;
enable_in &amp;lt;= &#039;1&#039;, &#039;0&#039; after 400 ns;&lt;br /&gt;
start &amp;lt;= &#039;1&#039;, &#039;0&#039; after 300 ns;&lt;br /&gt;
do_add &amp;lt;= &#039;1&#039;, &#039;0&#039; after 660 ns;&lt;br /&gt;
do_subtract &amp;lt;= &#039;0&#039;;&lt;br /&gt;
do_hold &amp;lt;= &#039;0&#039;;&lt;br /&gt;
data_in &amp;lt;= X&amp;quot;3&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
--Test process for å samanlikne utsignala kvart nanosekund.&lt;br /&gt;
test : process&lt;br /&gt;
begin&lt;br /&gt;
wait for 1 ns;&lt;br /&gt;
assert (data_out = data_out_synt)&lt;br /&gt;
report &amp;quot;Data ut er ulik&amp;quot;&lt;br /&gt;
severity Error;&lt;br /&gt;
end process test;&lt;br /&gt;
&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=IHP_130nm_process&amp;diff=2773</id>
		<title>IHP 130nm process</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=IHP_130nm_process&amp;diff=2773"/>
		<updated>2020-10-15T11:30:42Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Cadence design with IHP 130nm process=&lt;br /&gt;
&lt;br /&gt;
==Starting up the IHP SG13S Design Kit==&lt;br /&gt;
&lt;br /&gt;
The following steps describe how to install the Process Design Kit and start a new design. &lt;br /&gt;
&lt;br /&gt;
Log on to the mikroserver:&lt;br /&gt;
 ssh -X mikroserver4&lt;br /&gt;
&lt;br /&gt;
The preferred shell is bash. When using another shell it will be necessary to change the installation routine and modify the initialization script accordingly.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;first time&#039;&#039;&#039; you are using the IHP design kit you should copy the user environment design to your chosen parent directory (e.g ~/ihp)&lt;br /&gt;
 cp -rp /eda/design_kits/ihp_sg13/SG13S_618_rev1.12.0/work/skel ~/ihp&lt;br /&gt;
&lt;br /&gt;
Change sh.cadence in ~/ihp/cds to suit your needs. In particular you must define $IHP_TECH and $PROJECT according to your local environment. Then set general and user Cadence environment variables by doing:&lt;br /&gt;
 source /eda/cadence/2019-20/scripts/analog.sh&lt;br /&gt;
 cd ~/ihp/cds/&lt;br /&gt;
 source /eda/design_kits/ihp_sg13/sh.cadence&lt;br /&gt;
 virtuoso &amp;amp;&lt;br /&gt;
&lt;br /&gt;
To avoid having to do this every time try to set up your environment like described in [[MikroserverSetup]]&lt;br /&gt;
&lt;br /&gt;
= Before starting designing =&lt;br /&gt;
&lt;br /&gt;
Read the Design Kit User Guide. It can be found on the SG13SFeatures tab on the Virtuoso console window, or in the folder &amp;quot;/eda/design_kits/ihp_sg13/SG13S_618_rev1.12.0/doc/pdf/&amp;quot; on the mikroserver. Make sure that your web browser is closed or started from the mikroserver, else the file will not be found.&lt;br /&gt;
&lt;br /&gt;
Other documents are found in &amp;quot;eda/design_kits/ihp_sg13/SG13S_618_rev1.12.0/doc/html/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]] [[Category:Integrated_Circuts]] [[Category:Cadence_Virtuoso]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=IHP_130nm_process&amp;diff=2772</id>
		<title>IHP 130nm process</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=IHP_130nm_process&amp;diff=2772"/>
		<updated>2020-10-15T09:20:58Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Cadence design with IHP 130nm process=&lt;br /&gt;
&lt;br /&gt;
==Starting up the IHP SG13S Design Kit==&lt;br /&gt;
&lt;br /&gt;
The following steps describe how to install the Process Design Kit and start a new design. &lt;br /&gt;
&lt;br /&gt;
Log on to the mikroserver:&lt;br /&gt;
 ssh -X mikroserver4&lt;br /&gt;
&lt;br /&gt;
The preferred shell is bash. When using another shell it will be necessary to change the installation routine and modify the initialization script accordingly.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;first time&#039;&#039;&#039; you are using the IHP design kit you should copy the user environment design to your chosen parent directory (e.g ~/ihp)&lt;br /&gt;
 cp -rp /eda/design_kits/ihp_sg13/SG13S_618_rev1.12.0/work/skel ~/ihp&lt;br /&gt;
&lt;br /&gt;
Change sh.cadence in ~/ihp/cds to suit your needs. In particular you must define $IHP_TECH and $PROJECT according to your local environment. Then set general and user Cadence environment variables by doing:&lt;br /&gt;
 source /eda/cadence/2019-20/scripts/analog.sh&lt;br /&gt;
 cd ~/ihp/cds/&lt;br /&gt;
 source /eda/design_kits/ihp_sg13/sh.cadence&lt;br /&gt;
 virtuoso &amp;amp;&lt;br /&gt;
&lt;br /&gt;
To avoid having to do this every time try to set up your environment like described in [[MikroserverSetup]]&lt;br /&gt;
&lt;br /&gt;
= Before starting layout =&lt;br /&gt;
&lt;br /&gt;
Read the Design Kit User Guide. It can be found on the SG13SFeatures tab on the Virtuoso console window, or in the folder &amp;quot;/eda/design_kits/ihp_sg13/SG13S_618_rev1.12.0/doc/pdf/&amp;quot; on the mikroserver. Make sure that your web browser is closed or started from the mikroserver, else the file will not be found.&lt;br /&gt;
&lt;br /&gt;
Other documents are found in &amp;quot;eda/design_kits/ihp_sg13/SG13S_618_rev1.12.0/doc/html/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]] [[Category:Integrated_Circuts]] [[Category:Cadence_Virtuoso]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Layout_XL_and_IHP_SG13S&amp;diff=2771</id>
		<title>Layout XL and IHP SG13S</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Layout_XL_and_IHP_SG13S&amp;diff=2771"/>
		<updated>2020-10-15T09:19:12Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Before starting layout =&lt;br /&gt;
&lt;br /&gt;
Read the Design Kit User Guide. It can be found on the SG13SFeatures tab on the Virtuoso console window, or in the folder &amp;quot;/eda/design_kits/ihp_sg13/SG13S_618_rev1.12.0/doc/pdf/&amp;quot; on the mikroserver. Especially the part of connecting the substrate (chapter 8.2) and layout (chapter 9). Also make sure you understand the Layout Rules document.&lt;br /&gt;
&lt;br /&gt;
Other documents are found in &amp;quot;eda/design_kits/ihp_sg13/SG13S_618_rev1.12.0/doc/html/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you&#039;re laying out just one cell (in our case a SRAM-cell) make sure it contains defined values and not just pPar(&amp;quot;&amp;quot;)-values. This makes it easier to produce the right transistor-sizes etc. If you do not want to change your schematic, make a copy to another cell (e.g. from &amp;quot;sram&amp;quot; to &amp;quot;sram-fixed&amp;quot;). &lt;br /&gt;
&lt;br /&gt;
= Layout XL =&lt;br /&gt;
&lt;br /&gt;
From the schematic click Launch -&amp;gt; Layout XL to open the layout environment.&lt;br /&gt;
&lt;br /&gt;
[[File:layout.png|200px]] [[File:layout2.png|200px]]&lt;br /&gt;
&lt;br /&gt;
Layout XL opens with a new black empty canvas. The schematic window also opens. This is very useful as when we add our devices in the layout we can see which device they represent in the schematic as they get highlighted.&lt;br /&gt;
&lt;br /&gt;
Before anything you must define some options to avoid a lot of DRC-errors down the line. In the Layout Rules-document we read what our drawing-grid restrictions are (bottom of page 10). In Layout XL press E to open the Display Options-window. Remember that all size-values are in micrometers. Set the X and Y Snap Spacing to reflect the grid rules. Now press Shift-E to open the Layout Editor Options. Set gravity on(you can turn this off later with the g-key if you dont like it), and aperture around 0.1. This defines the the distance before snapping to another object etc.&lt;br /&gt;
&lt;br /&gt;
[[File:grid.png|200px]] [[File:gravity.png|200px]]&lt;br /&gt;
&lt;br /&gt;
= Generate from source =&lt;br /&gt;
&lt;br /&gt;
IHP has already defined transistors, pins, etc. for different sized, so it is not needed to draw these from scratch. You should, however, dissect them to understand how they work. To place all the devices from the schematic press Connectivity -&amp;gt; Generate -&amp;gt; All From Source. In this window we define which of our devices we want to place, the I/O pins, PR boundary (the area which our cell must be within) and floorplan settings (if needed). For our cell we need to change the IO-pins. We want the gnd and bit-lines to be vertical, and vdd and word-lines to be horizontal. This means that they will intersect each other and must be in different layers. We also want two gnd-pins which also can be defined here. Remember to uncheck Create under the sub!-pin since this is not needed. &lt;br /&gt;
&lt;br /&gt;
Change the Label options to a smaller font size (about 0.1 is ok). Click OK to see the results.&lt;br /&gt;
&lt;br /&gt;
[[File:result.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The purple box is the PR boundary in which are layout must be contained. Notice how the ntap1 is highlighted in the schematic when clicked in the layout window.&lt;br /&gt;
&lt;br /&gt;
= Pin Placement =&lt;br /&gt;
&lt;br /&gt;
Press Place -&amp;gt; Pin Placement. This opens a windows that lets us define the position of our pins. This is very helpful to line up our design. Remember that the positions may be tweaked later.&lt;br /&gt;
&lt;br /&gt;
[[File:pinplacement.png|400px]]&lt;br /&gt;
&lt;br /&gt;
= Placing devices =&lt;br /&gt;
&lt;br /&gt;
If you are extremely lazy you can autoplace the components with Place -&amp;gt; Custom Digital -&amp;gt; Placer. This, however, will probably not give you the desired result. To help you place the the devices correctly it is helpful to see which devices that connect to each other and how. This is accomplished with Connectivity -&amp;gt; Nets -&amp;gt; Show/Hide All Incomplete Nets. This will give you a all the nets that are uncompleted and can be very daunting. However, you can use Ctrl++ (that is Ctrl and +-key ) to turn on or off the nets for the selected device. &lt;br /&gt;
&lt;br /&gt;
F4 switches between Full and Partial Select. Partial Select means that we are able to select individual pieces of a device, e.g. if we want to stretch a part.&lt;br /&gt;
&lt;br /&gt;
[[File:partial.png|50px]] [[File:partial2.png|50px]]&lt;br /&gt;
&lt;br /&gt;
== DRD ==&lt;br /&gt;
[[File:DRDbuttons.png|50px]]&lt;br /&gt;
&lt;br /&gt;
DRD stands for Dynamic Design Rule Checking and are helpful while laying out your design. DRD Enforce On prevents you from doing anything that breaks the rules, and DRD Notify tells you if what you are doing is illegal. Image below shows example of DRD Notify.&lt;br /&gt;
&lt;br /&gt;
[[File:DRD.png|200px]]&lt;br /&gt;
&lt;br /&gt;
== Drawing ==&lt;br /&gt;
&lt;br /&gt;
To draw rectangles (e.g. NWell) choose the wanted layer on the left side then press R. To create a connection between to nodes you can either create a wire (Ctrl+W) or a path (P). A wire automatically helps with choosing layer, and may also be used to create vias to another layer by left-clicking.&lt;br /&gt;
&lt;br /&gt;
A complete layout could look something like this:&lt;br /&gt;
&lt;br /&gt;
[[File:sram.png|600px]]&lt;br /&gt;
&lt;br /&gt;
Note that there is a specified minimum enclosure in the design rules for vias between polysilicon and metal. This is because during the manufacturing process, the polysilicon and metal layers are created separately and the alignment is not perfect, so the polysilicon connection must be slightly larger to accommodate the potential offset between these layers. Enclosures can be seen by the polysilicon squares on the vias connecting the Q and Q_B lines in the design above. To set a via enclosure size, right click the via and go to properties. On the bottom, there is a setting for GatPoly enclosure. You must set each direction separately. &lt;br /&gt;
&lt;br /&gt;
= DRC =&lt;br /&gt;
&lt;br /&gt;
Run DRC by pressing Assura -&amp;gt; Run DRC. Make sure technology is SG13_dev and the Rule Set is default. Read about the different switches in the user guide (e.g. antenna-rules etc). If everything is ok this message should appear:&lt;br /&gt;
&lt;br /&gt;
[[File:drcok.png|200px]]&lt;br /&gt;
&lt;br /&gt;
The DRC should also be run for Density. See IHP user guide for how to produce dummy metal to fill the design.&lt;br /&gt;
&lt;br /&gt;
= LVS =&lt;br /&gt;
&lt;br /&gt;
This is covered in chapter 12 of the user guide.&lt;br /&gt;
&lt;br /&gt;
Run LVS by pressing Assura -&amp;gt; Run LVS. This will give you a match if the schematic and the layout match each other, or you will get some errors.&lt;br /&gt;
&lt;br /&gt;
[[File:LVS_summary.png|200px]]&lt;br /&gt;
&lt;br /&gt;
= Parasitic extraction QRC =&lt;br /&gt;
&lt;br /&gt;
This is covered in chapter 14 of the user guide. Before you run the QRC, the LVS has to match.&lt;br /&gt;
&lt;br /&gt;
To do an extraction of your circuit click Assura -&amp;gt; Run Quantus. In &amp;quot;Setup Dir&amp;quot; make sure the path is set to &amp;quot;/eda/design_kits/ihp_sg13/SG13S_616_rev1.0.2_a/Assura_SG13/qrc&amp;quot;, where the technology files for the qrc run is. Set the &amp;quot;Parasitic Res Component&amp;quot; to &amp;quot;presistor ivpcell SG13_dev&amp;quot; and the &amp;quot;Parasitic Cap Component&amp;quot; to &amp;quot;pcapacitor ivpcell SG13_dev&amp;quot;. Open the Extraction tab and set your ground net (gnd!) in the &amp;quot;Reference node&amp;quot; box. Then run the QRC by pressing OK.&lt;br /&gt;
&lt;br /&gt;
[[File:ASSURA_QRC.png|400px]]&lt;br /&gt;
&lt;br /&gt;
This should give you an extracted design called &amp;quot;av_extracted&amp;quot; in the cell of the library. This can be checked and viewed from the library manager. In this picture the extracted cell is a SRAM with bitline conditioning and a write driver.&lt;br /&gt;
&lt;br /&gt;
[[File:Extracted_layout_SRAM_with_bt_wd.png|400px]]&lt;br /&gt;
&lt;br /&gt;
= Post layout simulation =&lt;br /&gt;
&lt;br /&gt;
In the library manager make an copy of the SRAM cell, to use as a test bench cell. Click file -&amp;gt; new -&amp;gt; Cell View and make an config file in your new test bench cell. Use &amp;quot;config&amp;quot; as the type, and click &amp;quot;ok&amp;quot;. In the new window click on the &amp;quot;Use template&amp;quot; and select &amp;quot;AMS&amp;quot;, and click &amp;quot;ok&amp;quot;. Then edit the view list and add &amp;quot;av_extracted&amp;quot; with the add box. Clicking ok will then bring you to the hierarchy editor.&lt;br /&gt;
&lt;br /&gt;
Then you need a test bench schematic. In your copied schematic you will have the whole SRAM or different symbols making up the SRAM, but for the simulation there should only be a symbol that matches the extracted layout. So go back to the schematic in the SRAM cell and make one symbol out of it. Put this symbol into the test bench schematic, and add the pins that are needed.&lt;br /&gt;
&lt;br /&gt;
Go back to the hierarchy editor and change the View to your test bench schematic and update the hierarchy. Then right click on the &amp;quot;view found&amp;quot; for the SRAM from the SRAM cell, and select the av_extracted.&lt;br /&gt;
&lt;br /&gt;
[[File:Hierarchy_editor.png|400px]]&lt;br /&gt;
&lt;br /&gt;
Then Launch -&amp;gt; ADE L to get the simulation setup. Setup -&amp;gt; Design and choose the config file from the test bench cell. Use the stimuli button to create the stimuli (copy the stimuli from the schematic simulation) for the test, and then run it.&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=IHP_130nm_process&amp;diff=2770</id>
		<title>IHP 130nm process</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=IHP_130nm_process&amp;diff=2770"/>
		<updated>2020-10-15T08:32:12Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Cadence design with IHP 130nm process=&lt;br /&gt;
&lt;br /&gt;
==Starting up the IHP SG13S Design Kit==&lt;br /&gt;
&lt;br /&gt;
The following steps describe how to install the Process Design Kit and start a new design. &lt;br /&gt;
&lt;br /&gt;
Log on to the mikroserver:&lt;br /&gt;
 ssh -X mikroserver4&lt;br /&gt;
&lt;br /&gt;
The preferred shell is bash. When using another shell it will be necessary to change the installation routine and modify the initialization script accordingly.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;first time&#039;&#039;&#039; you are using the IHP design kit you should copy the user environment design to your chosen parent directory (e.g ~/ihp)&lt;br /&gt;
 cp -rp /eda/design_kits/ihp_sg13/SG13S_618_rev1.12.0/work/skel ~/ihp&lt;br /&gt;
&lt;br /&gt;
Change sh.cadence in ~/ihp/cds to suit your needs. In particular you must define $IHP_TECH and $PROJECT according to your local environment. Then set general and user Cadence environment variables by doing:&lt;br /&gt;
 source /eda/cadence/2019-20/scripts/analog.sh&lt;br /&gt;
 cd ~/ihp/cds/&lt;br /&gt;
 source /eda/design_kits/ihp_sg13/sh.cadence&lt;br /&gt;
 virtuoso &amp;amp;&lt;br /&gt;
&lt;br /&gt;
To avoid having to do this every time try to set up your environment like described in [[MikroserverSetup]]&lt;br /&gt;
&lt;br /&gt;
Follow the Design Kit User manual found in the menu SG13S Features &amp;gt; Design Kit Documentation. Make sure that your web browser is closed or started from the microserver, else the file will not be found.&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]] [[Category:Integrated_Circuts]] [[Category:Cadence_Virtuoso]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Layout_XL_and_IHP_SG13S&amp;diff=2769</id>
		<title>Layout XL and IHP SG13S</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Layout_XL_and_IHP_SG13S&amp;diff=2769"/>
		<updated>2020-10-15T08:07:40Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Before starting layout =&lt;br /&gt;
&lt;br /&gt;
Read the Design Kit User Guide. The user guide &amp;quot;SG13_user_guide.pdf&amp;quot; can be also be found in the folder &amp;quot;/eda/design_kits/ihp_sg13/SG13S_618_rev1.12.0/doc/pdf/&amp;quot; on the microserver.&lt;br /&gt;
Especially the part of connecting the substrate (chapter 8.2) and layout (chapter 9). Also make sure you understand the Layout Rules document.&lt;br /&gt;
&lt;br /&gt;
[[File:SG13 Design Kit User Guide.pdf]]&lt;br /&gt;
&lt;br /&gt;
[[File:SG13 Layout rules.pdf]]&lt;br /&gt;
&lt;br /&gt;
[[File:Documentation.png|200px]]&lt;br /&gt;
&lt;br /&gt;
If you&#039;re laying out just one cell (in our case a SRAM-cell) make sure it contains defined values and not just pPar(&amp;quot;&amp;quot;)-values. This makes it easier to produce the right transistor-sizes etc. If you do not want to change your schematic, make a copy to another cell (e.g. from &amp;quot;sram&amp;quot; to &amp;quot;sram-fixed&amp;quot;). &lt;br /&gt;
&lt;br /&gt;
= Layout XL =&lt;br /&gt;
&lt;br /&gt;
From the schematic click Launch -&amp;gt; Layout XL to open the layout environment.&lt;br /&gt;
&lt;br /&gt;
[[File:layout.png|200px]] [[File:layout2.png|200px]]&lt;br /&gt;
&lt;br /&gt;
Layout XL opens with a new black empty canvas. The schematic window also opens. This is very useful as when we add our devices in the layout we can see which device they represent in the schematic as they get highlighted.&lt;br /&gt;
&lt;br /&gt;
Before anything you must define some options to avoid a lot of DRC-errors down the line. In the Layout Rules-document we read what our drawing-grid restrictions are (bottom of page 10). In Layout XL press E to open the Display Options-window. Remember that all size-values are in micrometers. Set the X and Y Snap Spacing to reflect the grid rules. Now press Shift-E to open the Layout Editor Options. Set gravity on(you can turn this off later with the g-key if you dont like it), and aperture around 0.1. This defines the the distance before snapping to another object etc.&lt;br /&gt;
&lt;br /&gt;
[[File:grid.png|200px]] [[File:gravity.png|200px]]&lt;br /&gt;
&lt;br /&gt;
= Generate from source =&lt;br /&gt;
&lt;br /&gt;
IHP has already defined transistors, pins, etc. for different sized, so it is not needed to draw these from scratch. You should, however, dissect them to understand how they work. To place all the devices from the schematic press Connectivity -&amp;gt; Generate -&amp;gt; All From Source. In this window we define which of our devices we want to place, the I/O pins, PR boundary (the area which our cell must be within) and floorplan settings (if needed). For our cell we need to change the IO-pins. We want the gnd and bit-lines to be vertical, and vdd and word-lines to be horizontal. This means that they will intersect each other and must be in different layers. We also want two gnd-pins which also can be defined here. Remember to uncheck Create under the sub!-pin since this is not needed. &lt;br /&gt;
&lt;br /&gt;
Change the Label options to a smaller font size (about 0.1 is ok). Click OK to see the results.&lt;br /&gt;
&lt;br /&gt;
[[File:result.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The purple box is the PR boundary in which are layout must be contained. Notice how the ntap1 is highlighted in the schematic when clicked in the layout window.&lt;br /&gt;
&lt;br /&gt;
= Pin Placement =&lt;br /&gt;
&lt;br /&gt;
Press Place -&amp;gt; Pin Placement. This opens a windows that lets us define the position of our pins. This is very helpful to line up our design. Remember that the positions may be tweaked later.&lt;br /&gt;
&lt;br /&gt;
[[File:pinplacement.png|400px]]&lt;br /&gt;
&lt;br /&gt;
= Placing devices =&lt;br /&gt;
&lt;br /&gt;
If you are extremely lazy you can autoplace the components with Place -&amp;gt; Custom Digital -&amp;gt; Placer. This, however, will probably not give you the desired result. To help you place the the devices correctly it is helpful to see which devices that connect to each other and how. This is accomplished with Connectivity -&amp;gt; Nets -&amp;gt; Show/Hide All Incomplete Nets. This will give you a all the nets that are uncompleted and can be very daunting. However, you can use Ctrl++ (that is Ctrl and +-key ) to turn on or off the nets for the selected device. &lt;br /&gt;
&lt;br /&gt;
F4 switches between Full and Partial Select. Partial Select means that we are able to select individual pieces of a device, e.g. if we want to stretch a part.&lt;br /&gt;
&lt;br /&gt;
[[File:partial.png|50px]] [[File:partial2.png|50px]]&lt;br /&gt;
&lt;br /&gt;
== DRD ==&lt;br /&gt;
[[File:DRDbuttons.png|50px]]&lt;br /&gt;
&lt;br /&gt;
DRD stands for Dynamic Design Rule Checking and are helpful while laying out your design. DRD Enforce On prevents you from doing anything that breaks the rules, and DRD Notify tells you if what you are doing is illegal. Image below shows example of DRD Notify.&lt;br /&gt;
&lt;br /&gt;
[[File:DRD.png|200px]]&lt;br /&gt;
&lt;br /&gt;
== Drawing ==&lt;br /&gt;
&lt;br /&gt;
To draw rectangles (e.g. NWell) choose the wanted layer on the left side then press R. To create a connection between to nodes you can either create a wire (Ctrl+W) or a path (P). A wire automatically helps with choosing layer, and may also be used to create vias to another layer by left-clicking.&lt;br /&gt;
&lt;br /&gt;
A complete layout could look something like this:&lt;br /&gt;
&lt;br /&gt;
[[File:sram.png|600px]]&lt;br /&gt;
&lt;br /&gt;
Note that there is a specified minimum enclosure in the design rules for vias between polysilicon and metal. This is because during the manufacturing process, the polysilicon and metal layers are created separately and the alignment is not perfect, so the polysilicon connection must be slightly larger to accommodate the potential offset between these layers. Enclosures can be seen by the polysilicon squares on the vias connecting the Q and Q_B lines in the design above. To set a via enclosure size, right click the via and go to properties. On the bottom, there is a setting for GatPoly enclosure. You must set each direction separately. &lt;br /&gt;
&lt;br /&gt;
= DRC =&lt;br /&gt;
&lt;br /&gt;
Run DRC by pressing Assura -&amp;gt; Run DRC. Make sure technology is SG13_dev and the Rule Set is default. Read about the different switches in the user guide (e.g. antenna-rules etc). If everything is ok this message should appear:&lt;br /&gt;
&lt;br /&gt;
[[File:drcok.png|200px]]&lt;br /&gt;
&lt;br /&gt;
The DRC should also be run for Density. See IHP user guide for how to produce dummy metal to fill the design.&lt;br /&gt;
&lt;br /&gt;
= LVS =&lt;br /&gt;
&lt;br /&gt;
This is covered in chapter 12 of the user guide.&lt;br /&gt;
&lt;br /&gt;
Run LVS by pressing Assura -&amp;gt; Run LVS. This will give you a match if the schematic and the layout match each other, or you will get some errors.&lt;br /&gt;
&lt;br /&gt;
[[File:LVS_summary.png|200px]]&lt;br /&gt;
&lt;br /&gt;
= Parasitic extraction QRC =&lt;br /&gt;
&lt;br /&gt;
This is covered in chapter 14 of the user guide. Before you run the QRC, the LVS has to match.&lt;br /&gt;
&lt;br /&gt;
To do an extraction of your circuit click Assura -&amp;gt; Run Quantus. In &amp;quot;Setup Dir&amp;quot; make sure the path is set to &amp;quot;/eda/design_kits/ihp_sg13/SG13S_616_rev1.0.2_a/Assura_SG13/qrc&amp;quot;, where the technology files for the qrc run is. Set the &amp;quot;Parasitic Res Component&amp;quot; to &amp;quot;presistor ivpcell SG13_dev&amp;quot; and the &amp;quot;Parasitic Cap Component&amp;quot; to &amp;quot;pcapacitor ivpcell SG13_dev&amp;quot;. Open the Extraction tab and set your ground net (gnd!) in the &amp;quot;Reference node&amp;quot; box. Then run the QRC by pressing OK.&lt;br /&gt;
&lt;br /&gt;
[[File:ASSURA_QRC.png|400px]]&lt;br /&gt;
&lt;br /&gt;
This should give you an extracted design called &amp;quot;av_extracted&amp;quot; in the cell of the library. This can be checked and viewed from the library manager. In this picture the extracted cell is a SRAM with bitline conditioning and a write driver.&lt;br /&gt;
&lt;br /&gt;
[[File:Extracted_layout_SRAM_with_bt_wd.png|400px]]&lt;br /&gt;
&lt;br /&gt;
= Post layout simulation =&lt;br /&gt;
&lt;br /&gt;
In the library manager make an copy of the SRAM cell, to use as a test bench cell. Click file -&amp;gt; new -&amp;gt; Cell View and make an config file in your new test bench cell. Use &amp;quot;config&amp;quot; as the type, and click &amp;quot;ok&amp;quot;. In the new window click on the &amp;quot;Use template&amp;quot; and select &amp;quot;AMS&amp;quot;, and click &amp;quot;ok&amp;quot;. Then edit the view list and add &amp;quot;av_extracted&amp;quot; with the add box. Clicking ok will then bring you to the hierarchy editor.&lt;br /&gt;
&lt;br /&gt;
Then you need a test bench schematic. In your copied schematic you will have the whole SRAM or different symbols making up the SRAM, but for the simulation there should only be a symbol that matches the extracted layout. So go back to the schematic in the SRAM cell and make one symbol out of it. Put this symbol into the test bench schematic, and add the pins that are needed.&lt;br /&gt;
&lt;br /&gt;
Go back to the hierarchy editor and change the View to your test bench schematic and update the hierarchy. Then right click on the &amp;quot;view found&amp;quot; for the SRAM from the SRAM cell, and select the av_extracted.&lt;br /&gt;
&lt;br /&gt;
[[File:Hierarchy_editor.png|400px]]&lt;br /&gt;
&lt;br /&gt;
Then Launch -&amp;gt; ADE L to get the simulation setup. Setup -&amp;gt; Design and choose the config file from the test bench cell. Use the stimuli button to create the stimuli (copy the stimuli from the schematic simulation) for the test, and then run it.&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=IHP_130nm_process&amp;diff=2768</id>
		<title>IHP 130nm process</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=IHP_130nm_process&amp;diff=2768"/>
		<updated>2020-10-15T07:58:27Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: Updated to new software distro and design kit&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Cadence design with IHP 130nm process=&lt;br /&gt;
&lt;br /&gt;
==Starting up the IHP SG13S Design Kit==&lt;br /&gt;
&lt;br /&gt;
The following steps describe how to install the Process Design Kit and start a new design. &lt;br /&gt;
&lt;br /&gt;
Log on to the mikroserver:&lt;br /&gt;
 ssh -X mikroserver4&lt;br /&gt;
&lt;br /&gt;
The preferred shell is bash. When using another shell it will be necessary to change the installation routine and modify the initialization script accordingly.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;first time&#039;&#039;&#039; you are using the IHP design kit you should copy the user environment design to your chosen parent directory (e.g ~/ihp)&lt;br /&gt;
 cp -rp /eda/design_kits/ihp_sg13/SG13S_618_rev1.12.0/work/skel ~/ihp&lt;br /&gt;
&lt;br /&gt;
Change sh.cadence in ~/ihp/cds to suit your needs. In particular you must define $IHP_TECH and $PROJECT according to your local environment. Then set general and user Cadence environment variables by doing:&lt;br /&gt;
 source /eda/cadence/2019-20/scripts/analog.sh&lt;br /&gt;
 cd ~/ihp/cds/&lt;br /&gt;
 source sh.cadence&lt;br /&gt;
 virtuoso &amp;amp;&lt;br /&gt;
&lt;br /&gt;
To avoid having to do this every time try to set up your environment like described in [[MikroserverSetup]]&lt;br /&gt;
&lt;br /&gt;
Follow the Design Kit User manual found in the menu SG13S Features &amp;gt; Design Kit Documentation. Make sure that your web browser is closed or started from the microserver, else the file will not be found.&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]] [[Category:Integrated_Circuts]] [[Category:Cadence_Virtuoso]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Symbolsk_l%C3%B8sning_av_nodeligninger_med_Matlab&amp;diff=2767</id>
		<title>Symbolsk løsning av nodeligninger med Matlab</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Symbolsk_l%C3%B8sning_av_nodeligninger_med_Matlab&amp;diff=2767"/>
		<updated>2020-09-23T11:39:47Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: Added calculation for all capacitors&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Using Kirchoff&#039;s current law (KCL) on a source follower configuration to find Vout as a function of Vin ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
% Using Kirchoff&#039;s current law (KCL) on a source follower configuration&lt;br /&gt;
% to find Vo as a function of Vin&lt;br /&gt;
% Kjetil Ullaland, 2020&lt;br /&gt;
&lt;br /&gt;
syms s Cdg Cgs Cds Vin Vo Vgs Zc gm Rl Rs R Av Avo&lt;br /&gt;
&lt;br /&gt;
%%&lt;br /&gt;
disp(&#039;Only Cgd with series resistor is considered (Zc)&#039;)&lt;br /&gt;
&lt;br /&gt;
eq1=(Vo-Vgs)/(R+Zc)+gm*Vgs+Vo/Rl == 0;&lt;br /&gt;
eq2=(Vgs-Vo)/(R+Zc)+(Vgs-Vin)/Rs == 0;&lt;br /&gt;
eq1=subs(eq1,Zc,1/(s*Cdg));&lt;br /&gt;
eq2=subs(eq2,Zc,1/(s*Cdg));&lt;br /&gt;
disp(&#039;KCL for circuit node 1:&#039;);&lt;br /&gt;
pretty(eq1);&lt;br /&gt;
disp(&#039;KCL for circuit node 2:&#039;);&lt;br /&gt;
pretty(eq2);&lt;br /&gt;
&lt;br /&gt;
disp(&#039;Solve for Vo and Vin and calculate Av (Vo/Vin):&#039;);&lt;br /&gt;
solved=solve(eq1,eq2,Vo,Vin);&lt;br /&gt;
Av=solved.Vo/solved.Vin;&lt;br /&gt;
pretty(simplify(Av));&lt;br /&gt;
&lt;br /&gt;
pretty(subs(Av,Rl*gm,Avo));&lt;br /&gt;
%%&lt;br /&gt;
disp(&#039;All MOST capasitors are considered&#039;)&lt;br /&gt;
&lt;br /&gt;
syms s Cdg Cgs Cds Vin Vo Vgs gm Rl Rs Av Avo&lt;br /&gt;
&lt;br /&gt;
eq1=(Vo-Vgs)*s*Cdg + gm*Vgs + Vo/Rl + Vo*s*Cds == 0;&lt;br /&gt;
eq2=(Vgs-Vin)/Rs + Vgs*s*Cgs + (Vgs-Vo)*s*Cdg == 0;&lt;br /&gt;
disp(&#039;KCL for circuit node 1:&#039;);&lt;br /&gt;
pretty(eq1);&lt;br /&gt;
disp(&#039;KCL for circuit node 2:&#039;);&lt;br /&gt;
pretty(eq2);&lt;br /&gt;
&lt;br /&gt;
disp(&#039;Solve for Vo and Vin and calculate Av (Vo/Vin):&#039;);&lt;br /&gt;
solved=solve(eq1,eq2,Vo,Vin);&lt;br /&gt;
Av=solved.Vo/solved.Vin;&lt;br /&gt;
pretty(simplify(Av));&lt;br /&gt;
&lt;br /&gt;
pretty(subs(Av,Rl*gm,Avo));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using Kirchoff&#039;s current law (KCL) on single transistor stage, fig. 9.18 to find Vo as a function of Is ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
% Using Kirchoff&#039;s current law (KCL) on single transistor stage, fig. 9.18&lt;br /&gt;
% to find Vo as a function of Is&lt;br /&gt;
% Kjetil Ullaland, 2020&lt;br /&gt;
&lt;br /&gt;
syms Vo V1 s gm R1 R2 C C1 C2 Is Zc Rz;&lt;br /&gt;
&lt;br /&gt;
%% With feedforward capacitor&lt;br /&gt;
eq1=(Vo-V1)/Zc+gm*V1+Vo/R2+Vo*s*C2==0;&lt;br /&gt;
eq2=(V1-Vo)/Zc+V1*s*C1+V1/R1+Is==0;&lt;br /&gt;
eq1=subs(eq1,Zc,1/(s*C));&lt;br /&gt;
eq2=subs(eq2,Zc,1/(s*C));&lt;br /&gt;
&lt;br /&gt;
disp(&#039;Solve for Vo and V1 and calculate Vo/Is with capacitor only in feedforward loop&#039;);&lt;br /&gt;
solved=solve(eq1,eq2,Vo,Is);&lt;br /&gt;
VoOnIs=solved.Vo/solved.Is;&lt;br /&gt;
pretty(simplify(VoOnIs));&lt;br /&gt;
&lt;br /&gt;
%% With series resistor and capacitor in feedforward loop&lt;br /&gt;
eq1=(Vo-V1)/(Zc+Rz)+gm*V1+Vo/R2+Vo*s*C2==0;&lt;br /&gt;
eq2=(V1-Vo)/(Zc+Rz)+V1*s*C1+V1/R1+Is==0;&lt;br /&gt;
eq1=subs(eq1,Zc,1/(s*C));&lt;br /&gt;
eq2=subs(eq2,Zc,1/(s*C));&lt;br /&gt;
&lt;br /&gt;
disp(&#039;Solve for Vo and V1 and calculate Vo/Is with resistor and capacitor in feedforward loop&#039;);&lt;br /&gt;
solved=solve(eq1,eq2,Vo,Is);&lt;br /&gt;
VoOnIs=solved.Vo/solved.Is;&lt;br /&gt;
pretty(simplify(VoOnIs));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Symbolsk_l%C3%B8sning_av_nodeligninger_med_Matlab&amp;diff=2766</id>
		<title>Symbolsk løsning av nodeligninger med Matlab</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Symbolsk_l%C3%B8sning_av_nodeligninger_med_Matlab&amp;diff=2766"/>
		<updated>2020-09-23T11:13:48Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Using Kirchoff&#039;s current law (KCL) on a source follower configuration to find Vout as a function of Vin ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
% Using Kirchoff&#039;s current law (KCL) on a source follower configuration&lt;br /&gt;
% to find Vo as a function of Vin&lt;br /&gt;
% Only Cgd is considered (Zc)&lt;br /&gt;
% Kjetil Ullaland&lt;br /&gt;
&lt;br /&gt;
syms s C Vin Vo Vgs Zc gm Rl Rs R Av Avo&lt;br /&gt;
&lt;br /&gt;
eq1=(Vo-Vgs)/(R+Zc)+gm*Vgs+Vo/Rl == 0;&lt;br /&gt;
eq2=(Vgs-Vo)/(R+Zc)+(Vgs-Vin)/Rs == 0;&lt;br /&gt;
eq1=subs(eq1,Zc,1/(s*C));&lt;br /&gt;
eq2=subs(eq2,Zc,1/(s*C));&lt;br /&gt;
disp(&#039;KCL for circuit node 1:&#039;);&lt;br /&gt;
pretty(eq1);&lt;br /&gt;
disp(&#039;KCL for circuit node 2:&#039;);&lt;br /&gt;
pretty(eq2);&lt;br /&gt;
&lt;br /&gt;
disp(&#039;Solve for Vo and Vin and calculate Av (Vo/Vin):&#039;);&lt;br /&gt;
solved=solve(eq1,eq2,Vo,Vin);&lt;br /&gt;
Av=solved.Vo/solved.Vin;&lt;br /&gt;
pretty(simplify(Av));&lt;br /&gt;
&lt;br /&gt;
pretty(subs(Av,Rl*gm,Avo));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using Kirchoff&#039;s current law (KCL) on single transistor stage, fig. 9.18 to find Vo as a function of Is ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
% Using Kirchoff&#039;s current law (KCL) on single transistor stage, fig. 9.18&lt;br /&gt;
% to find Vo as a function of Is&lt;br /&gt;
% Kjetil Ullaland, 2020&lt;br /&gt;
&lt;br /&gt;
syms Vo V1 s gm R1 R2 C C1 C2 Is Zc Rz;&lt;br /&gt;
&lt;br /&gt;
%% With feedforward capacitor&lt;br /&gt;
eq1=(Vo-V1)/Zc+gm*V1+Vo/R2+Vo*s*C2==0;&lt;br /&gt;
eq2=(V1-Vo)/Zc+V1*s*C1+V1/R1+Is==0;&lt;br /&gt;
eq1=subs(eq1,Zc,1/(s*C));&lt;br /&gt;
eq2=subs(eq2,Zc,1/(s*C));&lt;br /&gt;
&lt;br /&gt;
disp(&#039;Solve for Vo and V1 and calculate Vo/Is with capacitor only in feedforward loop&#039;);&lt;br /&gt;
solved=solve(eq1,eq2,Vo,Is);&lt;br /&gt;
VoOnIs=solved.Vo/solved.Is;&lt;br /&gt;
pretty(simplify(VoOnIs));&lt;br /&gt;
&lt;br /&gt;
%% With series resistor and capacitor in feedforward loop&lt;br /&gt;
eq1=(Vo-V1)/(Zc+Rz)+gm*V1+Vo/R2+Vo*s*C2==0;&lt;br /&gt;
eq2=(V1-Vo)/(Zc+Rz)+V1*s*C1+V1/R1+Is==0;&lt;br /&gt;
eq1=subs(eq1,Zc,1/(s*C));&lt;br /&gt;
eq2=subs(eq2,Zc,1/(s*C));&lt;br /&gt;
&lt;br /&gt;
disp(&#039;Solve for Vo and V1 and calculate Vo/Is with resistor and capacitor in feedforward loop&#039;);&lt;br /&gt;
solved=solve(eq1,eq2,Vo,Is);&lt;br /&gt;
VoOnIs=solved.Vo/solved.Is;&lt;br /&gt;
pretty(simplify(VoOnIs));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Symbolsk_l%C3%B8sning_av_nodeligninger_med_Matlab&amp;diff=2765</id>
		<title>Symbolsk løsning av nodeligninger med Matlab</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Symbolsk_l%C3%B8sning_av_nodeligninger_med_Matlab&amp;diff=2765"/>
		<updated>2020-09-23T11:02:34Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: Updated for newer Matalb versions (tested on R2020b)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Using Kirchoff&#039;s current law (KCL) on a source follower configuration to find Vout as a function of Vin ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
% Using Kirchoff&#039;s current law (KCL) on a source follower configuration&lt;br /&gt;
% to find Vo as a function of Vin&lt;br /&gt;
% Only Cgd is considered (Zc)&lt;br /&gt;
% Kjetil Ullaland&lt;br /&gt;
&lt;br /&gt;
syms s C Vin Vo Vgs Zc gm Rl Rs R Av Avo&lt;br /&gt;
&lt;br /&gt;
eq1=(Vo-Vgs)/(R+Zc)+gm*Vgs+Vo/Rl == 0;&lt;br /&gt;
eq2=(Vgs-Vo)/(R+Zc)+(Vgs-Vin)/Rs == 0;&lt;br /&gt;
eq1=subs(eq1,Zc,1/(s*C));&lt;br /&gt;
eq2=subs(eq2,Zc,1/(s*C));&lt;br /&gt;
disp(&#039;KCL for circuit node 1:&#039;);&lt;br /&gt;
pretty(eq1);&lt;br /&gt;
disp(&#039;KCL for circuit node 2:&#039;);&lt;br /&gt;
pretty(eq2);&lt;br /&gt;
&lt;br /&gt;
disp(&#039;Solve for Vo and Vin and calculate Av (Vo/Vin):&#039;);&lt;br /&gt;
solved=solve(eq1,eq2,Vo,Vin);&lt;br /&gt;
Av=solved.Vo/solved.Vin;&lt;br /&gt;
pretty(simplify(Av));&lt;br /&gt;
&lt;br /&gt;
pretty(subs(Av,Rl*gm,Avo));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using Kirchoff&#039;s current law (KCL) on single transistor stage, fig. 9.18 to find Vo as a function of Is ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
% Using Kirchoff&#039;s current law (KCL) on single transistor stage, fig. 9.18&lt;br /&gt;
% to find Vo as a function of Is&lt;br /&gt;
% Kjetil Ullaland, 2015&lt;br /&gt;
&lt;br /&gt;
syms Vo V1 s gm R1 R2 C C1 C2 Is Zc Rz;&lt;br /&gt;
&lt;br /&gt;
%% With feedforward capacitor&lt;br /&gt;
eq1=sym(&#039;(Vo-V1)/Zc+gm*V1+Vo/R2+Vo*s*C2=0&#039;);&lt;br /&gt;
eq2=sym(&#039;(V1-Vo)/Zc+V1*s*C1+V1/R1+Is=0&#039;);&lt;br /&gt;
eq1=subs(eq1,Zc,&#039;1/(s*C)&#039;);&lt;br /&gt;
eq2=subs(eq2,Zc,&#039;1/(s*C)&#039;);&lt;br /&gt;
&lt;br /&gt;
solV1=solve(eq2,V1);&lt;br /&gt;
eq3=subs(eq1,V1,solV1);&lt;br /&gt;
SolVo=simplify(solve(eq3,[Vo]));&lt;br /&gt;
disp(&#039;With capacitor only in feedforward loop&#039;);&lt;br /&gt;
pretty(simplify(SolVo/Is));&lt;br /&gt;
&lt;br /&gt;
%% With series resistor and capacitor in feedforward loop&lt;br /&gt;
eq1=sym(&#039;(Vo-V1)/(Zc+Rz)+gm*V1+Vo/R2+Vo*s*C2=0&#039;);&lt;br /&gt;
eq2=sym(&#039;(V1-Vo)/(Zc+Rz)+V1*s*C1+V1/R1+Is=0&#039;);&lt;br /&gt;
eq1=subs(eq1,Zc,&#039;1/(s*C)&#039;);&lt;br /&gt;
eq2=subs(eq2,Zc,&#039;1/(s*C)&#039;);&lt;br /&gt;
&lt;br /&gt;
solV1=solve(eq2,V1);&lt;br /&gt;
eq3=simplify(subs(eq1,V1,solV1));&lt;br /&gt;
SolVo=solve(eq3,[Vo]);&lt;br /&gt;
disp(&#039;With series resistor and capacitor in feedforward loop&#039;);&lt;br /&gt;
pretty(simplify(SolVo/Is));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=PHYS222&amp;diff=2764</id>
		<title>PHYS222</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=PHYS222&amp;diff=2764"/>
		<updated>2020-09-07T13:37:04Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: /* Prosessteknologi */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Fagressurser for bruk i PHYS222 og PHYS223 ==&lt;br /&gt;
&lt;br /&gt;
=== Fagbøker ===&lt;br /&gt;
* [http://www.cmosvlsi.com/ CMOS VLSI Design: A Circuits and Systems Perspective]&lt;br /&gt;
* [http://www.ece.ucdavis.edu/sscrl/book_corrections/ghlm/corr/ List of known errors and corrections for Analysis and Design of Analog Integrated Circuits, Fourth Edition]&lt;br /&gt;
&lt;br /&gt;
==== Tutorials ====&lt;br /&gt;
* [http://www.electronics-tutorials.ws Basic Electronics Tutorials]&lt;br /&gt;
&lt;br /&gt;
=== Noise ===&lt;br /&gt;
* [http://ieeexplore.ieee.org/search/srchabstract.jsp?arnumber=261888&amp;amp;isnumber=6598&amp;amp;punumber=101&amp;amp;k2dockey=261888@ieeejrns&amp;amp;query=261888%3Cin%3Earnumber&amp;amp;pos=0 White noise in MOS transistors and resistors]&lt;br /&gt;
* [http://www.stat.ualberta.ca/people/schmu/preprints/poisson.pdf Shark attacks and the Poisson approximation]&lt;br /&gt;
* [https://www.k-state.edu/edl/docs/pubs/technical-resources/Technote1.pdf Equivalent Noise Bandwidth]&lt;br /&gt;
&lt;br /&gt;
=== Halvlederfysikk ===&lt;br /&gt;
* [https://www.youtube.com/watch?v=Coy-WRCfems How does a diode work?]&lt;br /&gt;
* [http://hyperphysics.phy-astr.gsu.edu/HBASE/solids/semcn.html Hyperphysics om halvledere]&lt;br /&gt;
* [http://jas.eng.buffalo.edu/index.html Semiconductor Simulation Applets]&lt;br /&gt;
* [http://pveducation.org/ Photovoltaic Education Network]&lt;br /&gt;
* [http://www.semi1source.com/glossary/ Semiconductor Glossary]&lt;br /&gt;
&lt;br /&gt;
=== Prosessteknologi ===&lt;br /&gt;
* [http://micro.magnet.fsu.edu/electromag/java/transistor/index.html Explore how an individual Field Effect (FET) transistor is fabricated on a silicon wafer simultaneously with millions of its neighbours]&lt;br /&gt;
* [https://www.youtube.com/watch?v=Jctk0DI7YP8 Understanding The FinFet Semiconductor Process]&lt;br /&gt;
* [https://youtu.be/MvbP_TizoNs Problems and Solutions at 7nm]&lt;br /&gt;
* [https://youtu.be/Qo2ywUURSKg A tour inside Intel Corporation&#039;s D1D factory]&lt;br /&gt;
* [https://www.youtube.com/watch?v=W3rfVpkNquA Intel Ivy Bridge 22nm FinFET Process Fabrication]&lt;br /&gt;
* [https://youtu.be/ApWOf6J858Y Integrated circuit scaling to 10 nm and beyond - Mark Bohr, Intel Senior Fellow]&lt;br /&gt;
* [http://spectrum.ieee.org/semiconductors/devices/transistor-wars Transistor Wars - Rival architectures face off in a bid to keep Moore&#039;s Law alive]&lt;br /&gt;
&lt;br /&gt;
=== Logical effort ===&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Logical_effort Logical Effort Wikipedia]&lt;br /&gt;
&lt;br /&gt;
=== Matlab/Maple ===&lt;br /&gt;
Vi kan bruke Matlab/Maple for å løse ligninger og plotte resultater. Her er noen eksempler:&lt;br /&gt;
&lt;br /&gt;
* [[Symbolsk løsning av nodeligninger med Matlab]]&lt;br /&gt;
* [http://lpsa.swarthmore.edu/Bode/BodeHow.html The Asymptotic Bode Diagram: Derivation of Approximations]&lt;br /&gt;
=== Kretssimulering ===&lt;br /&gt;
&lt;br /&gt;
[[ Eksempler/Oppgaver ]]&lt;br /&gt;
&lt;br /&gt;
==== AIM-Spice ====&lt;br /&gt;
AIM-Spice is a new version of SPICE running under the Microsoft Windows and Linux operating systems. AIM-Spice for Windows is capable of displaying graphically the results of a simulation in progress, a feature that allows the operator to terminate a run based on an instant information on intermediate simulation results.&lt;br /&gt;
&lt;br /&gt;
SPICE is the most commonly used analogue circuit simulator today and is enormously important for the electronics industry. SPICE is a general purpose analogue simulator which contains models for most circuit elements and can handle complex non-linear circuits. The simulator can calculate dc operating points, perform transient analyses, locate poles and zeros for different kinds of transfer functions, find the small signal frequency response, small signal transfer functions, small signal sensitivities, and perform Fourier, noise, and distortion analyses.&lt;br /&gt;
&lt;br /&gt;
[http://www.aimspice.com/download.html Download a free student version]&lt;br /&gt;
&lt;br /&gt;
==== LTspice ====&lt;br /&gt;
&lt;br /&gt;
LTspice is a high performance Spice III simulator, schematic capture and waveform viewer with enhancements and models for easing the simulation of switching regulators. Included in this download are Spice, Macro Models for 80% of Linear Technology&#039;s switching regulators, over 200 op amp models, as well as resistors, transistors and MOSFET models. &lt;br /&gt;
&lt;br /&gt;
[http://www.linear.com/designtools/software/switchercad.jsp Download LTspice]&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=PHYS222&amp;diff=2763</id>
		<title>PHYS222</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=PHYS222&amp;diff=2763"/>
		<updated>2020-09-07T13:33:13Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: /* Prosessteknologi */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Fagressurser for bruk i PHYS222 og PHYS223 ==&lt;br /&gt;
&lt;br /&gt;
=== Fagbøker ===&lt;br /&gt;
* [http://www.cmosvlsi.com/ CMOS VLSI Design: A Circuits and Systems Perspective]&lt;br /&gt;
* [http://www.ece.ucdavis.edu/sscrl/book_corrections/ghlm/corr/ List of known errors and corrections for Analysis and Design of Analog Integrated Circuits, Fourth Edition]&lt;br /&gt;
&lt;br /&gt;
==== Tutorials ====&lt;br /&gt;
* [http://www.electronics-tutorials.ws Basic Electronics Tutorials]&lt;br /&gt;
&lt;br /&gt;
=== Noise ===&lt;br /&gt;
* [http://ieeexplore.ieee.org/search/srchabstract.jsp?arnumber=261888&amp;amp;isnumber=6598&amp;amp;punumber=101&amp;amp;k2dockey=261888@ieeejrns&amp;amp;query=261888%3Cin%3Earnumber&amp;amp;pos=0 White noise in MOS transistors and resistors]&lt;br /&gt;
* [http://www.stat.ualberta.ca/people/schmu/preprints/poisson.pdf Shark attacks and the Poisson approximation]&lt;br /&gt;
* [https://www.k-state.edu/edl/docs/pubs/technical-resources/Technote1.pdf Equivalent Noise Bandwidth]&lt;br /&gt;
&lt;br /&gt;
=== Halvlederfysikk ===&lt;br /&gt;
* [https://www.youtube.com/watch?v=Coy-WRCfems How does a diode work?]&lt;br /&gt;
* [http://hyperphysics.phy-astr.gsu.edu/HBASE/solids/semcn.html Hyperphysics om halvledere]&lt;br /&gt;
* [http://jas.eng.buffalo.edu/index.html Semiconductor Simulation Applets]&lt;br /&gt;
* [http://pveducation.org/ Photovoltaic Education Network]&lt;br /&gt;
* [http://www.semi1source.com/glossary/ Semiconductor Glossary]&lt;br /&gt;
&lt;br /&gt;
=== Prosessteknologi ===&lt;br /&gt;
* [http://micro.magnet.fsu.edu/electromag/java/transistor/index.html Explore how an individual Field Effect (FET) transistor is fabricated on a silicon wafer simultaneously with millions of its neighbours]&lt;br /&gt;
* [https://www.youtube.com/watch?v=Jctk0DI7YP8 Understanding The FinFet Semiconductor Process]&lt;br /&gt;
* [https://youtu.be/MvbP_TizoNs Problems and Solutions at 7nm]&lt;br /&gt;
* [https://youtu.be/Qo2ywUURSKg A tour inside Intel Corporation&#039;s D1D factory]&lt;br /&gt;
* [https://www.youtube.com/watch?v=W3rfVpkNquA Intel Ivy Bridge 22nm FinFET Process Fabrication]&lt;br /&gt;
* [http://spectrum.ieee.org/semiconductors/devices/transistor-wars Transistor Wars - Rival architectures face off in a bid to keep Moore&#039;s Law alive]&lt;br /&gt;
&lt;br /&gt;
=== Logical effort ===&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Logical_effort Logical Effort Wikipedia]&lt;br /&gt;
&lt;br /&gt;
=== Matlab/Maple ===&lt;br /&gt;
Vi kan bruke Matlab/Maple for å løse ligninger og plotte resultater. Her er noen eksempler:&lt;br /&gt;
&lt;br /&gt;
* [[Symbolsk løsning av nodeligninger med Matlab]]&lt;br /&gt;
* [http://lpsa.swarthmore.edu/Bode/BodeHow.html The Asymptotic Bode Diagram: Derivation of Approximations]&lt;br /&gt;
=== Kretssimulering ===&lt;br /&gt;
&lt;br /&gt;
[[ Eksempler/Oppgaver ]]&lt;br /&gt;
&lt;br /&gt;
==== AIM-Spice ====&lt;br /&gt;
AIM-Spice is a new version of SPICE running under the Microsoft Windows and Linux operating systems. AIM-Spice for Windows is capable of displaying graphically the results of a simulation in progress, a feature that allows the operator to terminate a run based on an instant information on intermediate simulation results.&lt;br /&gt;
&lt;br /&gt;
SPICE is the most commonly used analogue circuit simulator today and is enormously important for the electronics industry. SPICE is a general purpose analogue simulator which contains models for most circuit elements and can handle complex non-linear circuits. The simulator can calculate dc operating points, perform transient analyses, locate poles and zeros for different kinds of transfer functions, find the small signal frequency response, small signal transfer functions, small signal sensitivities, and perform Fourier, noise, and distortion analyses.&lt;br /&gt;
&lt;br /&gt;
[http://www.aimspice.com/download.html Download a free student version]&lt;br /&gt;
&lt;br /&gt;
==== LTspice ====&lt;br /&gt;
&lt;br /&gt;
LTspice is a high performance Spice III simulator, schematic capture and waveform viewer with enhancements and models for easing the simulation of switching regulators. Included in this download are Spice, Macro Models for 80% of Linear Technology&#039;s switching regulators, over 200 op amp models, as well as resistors, transistors and MOSFET models. &lt;br /&gt;
&lt;br /&gt;
[http://www.linear.com/designtools/software/switchercad.jsp Download LTspice]&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=PHYS222&amp;diff=2762</id>
		<title>PHYS222</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=PHYS222&amp;diff=2762"/>
		<updated>2020-09-07T13:26:55Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: /* Prosessteknologi */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Fagressurser for bruk i PHYS222 og PHYS223 ==&lt;br /&gt;
&lt;br /&gt;
=== Fagbøker ===&lt;br /&gt;
* [http://www.cmosvlsi.com/ CMOS VLSI Design: A Circuits and Systems Perspective]&lt;br /&gt;
* [http://www.ece.ucdavis.edu/sscrl/book_corrections/ghlm/corr/ List of known errors and corrections for Analysis and Design of Analog Integrated Circuits, Fourth Edition]&lt;br /&gt;
&lt;br /&gt;
==== Tutorials ====&lt;br /&gt;
* [http://www.electronics-tutorials.ws Basic Electronics Tutorials]&lt;br /&gt;
&lt;br /&gt;
=== Noise ===&lt;br /&gt;
* [http://ieeexplore.ieee.org/search/srchabstract.jsp?arnumber=261888&amp;amp;isnumber=6598&amp;amp;punumber=101&amp;amp;k2dockey=261888@ieeejrns&amp;amp;query=261888%3Cin%3Earnumber&amp;amp;pos=0 White noise in MOS transistors and resistors]&lt;br /&gt;
* [http://www.stat.ualberta.ca/people/schmu/preprints/poisson.pdf Shark attacks and the Poisson approximation]&lt;br /&gt;
* [https://www.k-state.edu/edl/docs/pubs/technical-resources/Technote1.pdf Equivalent Noise Bandwidth]&lt;br /&gt;
&lt;br /&gt;
=== Halvlederfysikk ===&lt;br /&gt;
* [https://www.youtube.com/watch?v=Coy-WRCfems How does a diode work?]&lt;br /&gt;
* [http://hyperphysics.phy-astr.gsu.edu/HBASE/solids/semcn.html Hyperphysics om halvledere]&lt;br /&gt;
* [http://jas.eng.buffalo.edu/index.html Semiconductor Simulation Applets]&lt;br /&gt;
* [http://pveducation.org/ Photovoltaic Education Network]&lt;br /&gt;
* [http://www.semi1source.com/glossary/ Semiconductor Glossary]&lt;br /&gt;
&lt;br /&gt;
=== Prosessteknologi ===&lt;br /&gt;
* [http://micro.magnet.fsu.edu/electromag/java/transistor/index.html Explore how an individual Field Effect (FET) transistor is fabricated on a silicon wafer simultaneously with millions of its neighbours]&lt;br /&gt;
* [https://www.youtube.com/watch?v=Jctk0DI7YP8 Understanding The FinFet Semiconductor Process]&lt;br /&gt;
* [https://youtu.be/MvbP_TizoNs Problems and Solutions at 7nm]&lt;br /&gt;
* [https://www.youtube.com/watch?v=W3rfVpkNquA Intel Ivy Bridge 22nm FinFET Process Fabrication]&lt;br /&gt;
* [http://spectrum.ieee.org/semiconductors/devices/transistor-wars Transistor Wars - Rival architectures face off in a bid to keep Moore&#039;s Law alive]&lt;br /&gt;
&lt;br /&gt;
=== Logical effort ===&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Logical_effort Logical Effort Wikipedia]&lt;br /&gt;
&lt;br /&gt;
=== Matlab/Maple ===&lt;br /&gt;
Vi kan bruke Matlab/Maple for å løse ligninger og plotte resultater. Her er noen eksempler:&lt;br /&gt;
&lt;br /&gt;
* [[Symbolsk løsning av nodeligninger med Matlab]]&lt;br /&gt;
* [http://lpsa.swarthmore.edu/Bode/BodeHow.html The Asymptotic Bode Diagram: Derivation of Approximations]&lt;br /&gt;
=== Kretssimulering ===&lt;br /&gt;
&lt;br /&gt;
[[ Eksempler/Oppgaver ]]&lt;br /&gt;
&lt;br /&gt;
==== AIM-Spice ====&lt;br /&gt;
AIM-Spice is a new version of SPICE running under the Microsoft Windows and Linux operating systems. AIM-Spice for Windows is capable of displaying graphically the results of a simulation in progress, a feature that allows the operator to terminate a run based on an instant information on intermediate simulation results.&lt;br /&gt;
&lt;br /&gt;
SPICE is the most commonly used analogue circuit simulator today and is enormously important for the electronics industry. SPICE is a general purpose analogue simulator which contains models for most circuit elements and can handle complex non-linear circuits. The simulator can calculate dc operating points, perform transient analyses, locate poles and zeros for different kinds of transfer functions, find the small signal frequency response, small signal transfer functions, small signal sensitivities, and perform Fourier, noise, and distortion analyses.&lt;br /&gt;
&lt;br /&gt;
[http://www.aimspice.com/download.html Download a free student version]&lt;br /&gt;
&lt;br /&gt;
==== LTspice ====&lt;br /&gt;
&lt;br /&gt;
LTspice is a high performance Spice III simulator, schematic capture and waveform viewer with enhancements and models for easing the simulation of switching regulators. Included in this download are Spice, Macro Models for 80% of Linear Technology&#039;s switching regulators, over 200 op amp models, as well as resistors, transistors and MOSFET models. &lt;br /&gt;
&lt;br /&gt;
[http://www.linear.com/designtools/software/switchercad.jsp Download LTspice]&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Microelectronics_group&amp;diff=2761</id>
		<title>Microelectronics group</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Microelectronics_group&amp;diff=2761"/>
		<updated>2020-08-18T14:11:34Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Øvinger og guider ==&lt;br /&gt;
=== Mentor Graphics ===&lt;br /&gt;
&lt;br /&gt;
* [[Expedition PCB]] Komme i gang med kretskortutlegg ved hjelp av Expedition PCB&lt;br /&gt;
&lt;br /&gt;
* [[Modelsim/Questa]] Skrive og simulere VHDL-kode med Mentor Graphics ModelSim&lt;br /&gt;
&lt;br /&gt;
=== Cadence ===&lt;br /&gt;
&lt;br /&gt;
* [[Cadence Virtuoso]]&lt;br /&gt;
&lt;br /&gt;
=== Microsemi ===&lt;br /&gt;
&lt;br /&gt;
* [[SmartFusion2- AMBA APB, Custom Peripheral]] Making a custom peripheral for the AMBA APB bus&lt;br /&gt;
&lt;br /&gt;
=== Xilinx ===&lt;br /&gt;
&lt;br /&gt;
* [[Xilinx Vivado]] Tutorials for Xilinx Vivado&lt;br /&gt;
&lt;br /&gt;
* [[Xilinx SDK]] Tutorials for Xilinx Software Development Kit&lt;br /&gt;
&lt;br /&gt;
=== Annet ===&lt;br /&gt;
* [[Bitvis UVVM VHDL Verification Component Framework]] &lt;br /&gt;
&lt;br /&gt;
* [[Tutorials]] Tutorials from the web&lt;br /&gt;
&lt;br /&gt;
* [[XJTAG]]  Boundary Scan with XJTAG&lt;br /&gt;
&lt;br /&gt;
* [[XJDeveloper]] Innføring i XJDeveloper&lt;br /&gt;
&lt;br /&gt;
* [[FreeRTOS]] Free Real Time Operating System&lt;br /&gt;
&lt;br /&gt;
== Andre fagressurser og laboratorieveiledninger==&lt;br /&gt;
&lt;br /&gt;
* [[MikroserverSetup]] Oppsett av enkel tilkobling til mikroserverene&lt;br /&gt;
&lt;br /&gt;
* [[PHYS222]] Fagressurser for PHYS222 og PHYS223&lt;br /&gt;
&lt;br /&gt;
* [[PHYS321]] Fagressurser for PHYS321&lt;br /&gt;
&lt;br /&gt;
* [[Teknisk hjelp]] Teknisk hjelp for bruk av DAK-programvare&lt;br /&gt;
&lt;br /&gt;
* [[BGA lodding]] bruk av Martin 09.6 XL BGA lodding maskin (intern)&lt;br /&gt;
&lt;br /&gt;
* [[Reflow Soldering]] Use of Technoprint HA-02 reflow oven&lt;br /&gt;
&lt;br /&gt;
== Populærvitenskaplig om elektronikk ==&lt;br /&gt;
* [https://youtu.be/NUUeGianTKM The Story of Electricity - BBC Documentary]&lt;br /&gt;
&lt;br /&gt;
* [https://www.youtube.com/watch?v=U4XknGqr3Bo Transiztorized! ]&lt;br /&gt;
&lt;br /&gt;
== Eldre øvinger og guider ==&lt;br /&gt;
=== Mentor Graphics ===&lt;br /&gt;
* [[IC studio]] Veiledning til IC-design ved hjelp av IC studio&lt;br /&gt;
&lt;br /&gt;
* [[IC studio - SPICE/Symbol Tutorial]] Relate a SPICE file to a Symbol&lt;br /&gt;
&lt;br /&gt;
* [[IC Station]] Tegne utlegg for integrerte kretser&lt;br /&gt;
&lt;br /&gt;
=== Annet ===&lt;br /&gt;
* [[PCI-eksperiment]] Øving med HLT-RORC-prototypekort&lt;br /&gt;
&lt;br /&gt;
* [[Xilinx]] Øving i bruk av Xilinx Project Studio&lt;br /&gt;
&lt;br /&gt;
* [[SmartFusion2]] Oppsett og design med SF2&lt;br /&gt;
&lt;br /&gt;
* [[FLTK GUI]] Graphical User Interface using FLTK&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=Microelectronics_group&amp;diff=2760</id>
		<title>Microelectronics group</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=Microelectronics_group&amp;diff=2760"/>
		<updated>2020-08-18T14:07:19Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Øvinger og guider ==&lt;br /&gt;
=== Mentor Graphics ===&lt;br /&gt;
&lt;br /&gt;
* [[Expedition PCB]] Komme i gang med kretskortutlegg ved hjelp av Expedition PCB&lt;br /&gt;
&lt;br /&gt;
* [[Modelsim/Questa]] Skrive og simulere VHDL-kode med Mentor Graphics ModelSim&lt;br /&gt;
&lt;br /&gt;
=== Cadence ===&lt;br /&gt;
&lt;br /&gt;
* [[Cadence Virtuoso]]&lt;br /&gt;
&lt;br /&gt;
=== Microsemi ===&lt;br /&gt;
&lt;br /&gt;
* [[SmartFusion2- AMBA APB, Custom Peripheral]] Making a custom peripheral for the AMBA APB bus&lt;br /&gt;
&lt;br /&gt;
=== Xilinx ===&lt;br /&gt;
&lt;br /&gt;
* [[Xilinx Vivado]] Tutorials for Xilinx Vivado&lt;br /&gt;
&lt;br /&gt;
* [[Xilinx SDK]] Tutorials for Xilinx Software Development Kit&lt;br /&gt;
&lt;br /&gt;
=== Annet ===&lt;br /&gt;
* [[Bitvis UVVM VHDL Verification Component Framework]] &lt;br /&gt;
&lt;br /&gt;
* [[Tutorials]] Tutorials from the web&lt;br /&gt;
&lt;br /&gt;
* [[XJTAG]]  Boundary Scan with XJTAG&lt;br /&gt;
&lt;br /&gt;
* [[XJDeveloper]] Innføring i XJDeveloper&lt;br /&gt;
&lt;br /&gt;
* [[FreeRTOS]] Free Real Time Operating System&lt;br /&gt;
&lt;br /&gt;
== Andre fagressurser og laboratorieveiledninger==&lt;br /&gt;
&lt;br /&gt;
* [[MikroserverSetup]] Oppsett av enkel tilkobling til mikroserverene&lt;br /&gt;
&lt;br /&gt;
* [[PHYS222]] Fagressurser for PHYS222 og PHYS223&lt;br /&gt;
&lt;br /&gt;
* [[PHYS321]] Fagressurser for PHYS321&lt;br /&gt;
&lt;br /&gt;
* [[Teknisk hjelp]] Teknisk hjelp for bruk av DAK-programvare&lt;br /&gt;
&lt;br /&gt;
* [[BGA lodding]] bruk av Martin 09.6 XL BGA lodding maskin (intern)&lt;br /&gt;
&lt;br /&gt;
* [[Reflow Soldering]] Use of Technoprint HA-02 reflow oven&lt;br /&gt;
&lt;br /&gt;
== Populærvitenskaplig om elektronikk ==&lt;br /&gt;
* [https://youtu.be/NUUeGianTKM The Story of Electricity - BBC Documentary]&lt;br /&gt;
&lt;br /&gt;
== Eldre øvinger og guider ==&lt;br /&gt;
=== Mentor Graphics ===&lt;br /&gt;
* [[IC studio]] Veiledning til IC-design ved hjelp av IC studio&lt;br /&gt;
&lt;br /&gt;
* [[IC studio - SPICE/Symbol Tutorial]] Relate a SPICE file to a Symbol&lt;br /&gt;
&lt;br /&gt;
* [[IC Station]] Tegne utlegg for integrerte kretser&lt;br /&gt;
&lt;br /&gt;
=== Annet ===&lt;br /&gt;
* [[PCI-eksperiment]] Øving med HLT-RORC-prototypekort&lt;br /&gt;
&lt;br /&gt;
* [[Xilinx]] Øving i bruk av Xilinx Project Studio&lt;br /&gt;
&lt;br /&gt;
* [[SmartFusion2]] Oppsett og design med SF2&lt;br /&gt;
&lt;br /&gt;
* [[FLTK GUI]] Graphical User Interface using FLTK&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=SSH_tunnel&amp;diff=2748</id>
		<title>SSH tunnel</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=SSH_tunnel&amp;diff=2748"/>
		<updated>2020-03-30T08:21:14Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==VNC-SSH innlogging==&lt;br /&gt;
===Opprette SSH tunnel===&lt;br /&gt;
&lt;br /&gt;
# Start opp SSH Secure Shell&lt;br /&gt;
# Velg Profiles → Add Profile… gi den et navn f.eks. &amp;quot;mikroserver2 via login&amp;quot;&lt;br /&gt;
# Velg Profiles → Edit Profiles…, velg mikroserver2 blant profiles i venstre felt.&lt;br /&gt;
# Velg Tunneling tab&lt;br /&gt;
# Velg Outgoing tab&lt;br /&gt;
## Klikk Add…&lt;br /&gt;
## Skriv inn et navn i Display Name feltet, f.eks. mikroserver2&lt;br /&gt;
## Pass på at Type er TCP&lt;br /&gt;
## Skriv inn 5900 i feltet Listen Port&lt;br /&gt;
## Sjekk at Allow Local Connections Only er krysset av&lt;br /&gt;
## Skriv inn mikroserver2 i Destination Host (adressen til maskinen du kjører VNC server på. Bruk fullt navn om nødvendig: host.klientdrift.uib.no)&lt;br /&gt;
## Skriv inn summen av 5900 og ditt desktop nummer, eks 5906, i feltet Destination Port&lt;br /&gt;
## Klikk OK&lt;br /&gt;
# Velg Conection tab&lt;br /&gt;
## Skriv inn login.uib.no i Host name feltet&lt;br /&gt;
## Skriv inn ditt unix-brukernavn i User name feltet&lt;br /&gt;
## Port number skal være 22&lt;br /&gt;
## la resten være som det er.&lt;br /&gt;
## Klikk OK (ferdig med konfigurasjon)&lt;br /&gt;
# Velg Profiles -&amp;gt; &amp;quot;mikroserver2 via login&amp;quot;&lt;br /&gt;
# Tast inn ditt unix-bruker passord&lt;br /&gt;
# Legg ned / minimize SSH vinduet, det kjører nå SSH tunnellen og må kjøre så lenge du bruke VNC Viewer via SSH.&lt;br /&gt;
# Når du er ferdig og har avsluttet VNC Viewer, logger du først ut fra serveren med kommandoen logout og så lukker du SSH vinduet.&lt;br /&gt;
&lt;br /&gt;
====Neste gang du skal opprette SSH tunnellen====&lt;br /&gt;
&lt;br /&gt;
# Start SSH Secure Shell&lt;br /&gt;
# Utfør punktene fra og med punkt 7 over.&lt;br /&gt;
&lt;br /&gt;
===Login til VNC-SSH server===&lt;br /&gt;
&lt;br /&gt;
Start først opp din egen VNC server som forklart i VNC innlogging mot egen server, eller bruk en eksisternde VNC server.&lt;br /&gt;
&lt;br /&gt;
Start VNC Viewer og skriv inn localhost (ikke :port) i Server feltet og click OK og tast inn ditt vnc passord.&lt;br /&gt;
&lt;br /&gt;
===Logout fra egen VNC-SSH server===&lt;br /&gt;
&lt;br /&gt;
Bruk samme fremgangsmåte som forklart under Metode 2 → Logout fra egen VNC server i VNC innlogging.&lt;br /&gt;
&lt;br /&gt;
===Problemer?===&lt;br /&gt;
&lt;br /&gt;
Om du får melding om at SSH tunnell ikke kunne opprettes, sjekk om du kjører VNC-server på din pc, den kan skape problemer.&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
	<entry>
		<id>http://ift.wiki.uib.no/index.php?title=IHP_130nm_process&amp;diff=2747</id>
		<title>IHP 130nm process</title>
		<link rel="alternate" type="text/html" href="http://ift.wiki.uib.no/index.php?title=IHP_130nm_process&amp;diff=2747"/>
		<updated>2020-03-30T08:10:28Z</updated>

		<summary type="html">&lt;p&gt;Nfyku: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Cadence design with IHP 130nm process=&lt;br /&gt;
&lt;br /&gt;
==Starting up the IHP SG13S Design Kit==&lt;br /&gt;
&lt;br /&gt;
The following steps describe how to install the Process Design Kit and start a new design. &lt;br /&gt;
&lt;br /&gt;
Log on to the mikroserver:&lt;br /&gt;
 ssh -X mikroserver4&lt;br /&gt;
&lt;br /&gt;
The preferred shell is bash. When using another shell it will be necessary to change the installation routine and modify the initialization script accordingly.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;first time&#039;&#039;&#039; you are using the IHP design kit you should copy the user environment design to your chosen parent directory (e.g ~/ihp)&lt;br /&gt;
 cp -rp  /eda/design_kits/ihp_sg13/SG13S_617_rev1.10.1/work/skel ~/ihp&lt;br /&gt;
&lt;br /&gt;
Change sh.cadence in ~/ihp/cds to suit your needs. In particular you must define $IHP_TECH and $PROJECT according to your local environment. Then set general and user Cadence environment variables by doing:&lt;br /&gt;
 source /eda/cadence/2018-19/scripts/analog.sh&lt;br /&gt;
 cd ~/ihp/cds/&lt;br /&gt;
 source sh.cadence&lt;br /&gt;
 virtuoso &amp;amp;&lt;br /&gt;
&lt;br /&gt;
To avoid having to do this every time try to set up your environment like described in [[MikroserverSetup]]&lt;br /&gt;
&lt;br /&gt;
Follow the Design Kit User manual found in the menu SG13S Features &amp;gt; Design Kit Documentation. Make sure that your web browser is closed or started from the microserver, else the file will not be found.&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikroelektronikk]] [[Category:Integrated_Circuts]] [[Category:Cadence_Virtuoso]]&lt;/div&gt;</summary>
		<author><name>Nfyku</name></author>
	</entry>
</feed>