<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>my tech blog</title>
	<atom:link href="http://billauer.co.il/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://billauer.co.il/blog</link>
	<description>Anything I found worthy to write down.</description>
	<lastBuildDate>Sat, 08 Jul 2017 08:18:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Fedora 12: Bringing keyboard autorepeat back</title>
		<link>http://billauer.co.il/blog/2017/07/linux-keyboard-auto-repeat/</link>
		<comments>http://billauer.co.il/blog/2017/07/linux-keyboard-auto-repeat/#comments</comments>
		<pubDate>Sun, 02 Jul 2017 13:03:40 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://billauer.co.il/blog/?p=5249</guid>
		<description><![CDATA[For some weird reason (actually, running an old Atari 800 emulator), my autorepeat was suddenly not working. On any window. That&#8217;s the moment one becomes aware of how often it&#8217;s used. Quick solution: $ xset r on and it was all fine again. Or $ xset q to see all settings.]]></description>
			<content:encoded><![CDATA[<p>For some weird reason (actually, running an old Atari 800 emulator), my autorepeat was suddenly not working. On any window. That&#8217;s the moment one becomes aware of how often it&#8217;s used.</p>
<p>Quick solution:</p>
<pre>$ xset r on</pre>
<p>and it was all fine again. Or</p>
<pre>$ xset q</pre>
<p>to see all settings.</p>
]]></content:encoded>
			<wfw:commentRss>http://billauer.co.il/blog/2017/07/linux-keyboard-auto-repeat/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Altera NIOS II jots</title>
		<link>http://billauer.co.il/blog/2017/06/intel-fpga-nios-jots/</link>
		<comments>http://billauer.co.il/blog/2017/06/intel-fpga-nios-jots/#comments</comments>
		<pubDate>Sat, 03 Jun 2017 07:03:08 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[Altera]]></category>
		<category><![CDATA[FPGA]]></category>

		<guid isPermaLink="false">http://billauer.co.il/blog/?p=5245</guid>
		<description><![CDATA[About this post These are things I wrote down at different stages of introducing myself to Nios II and its environment. Nothing really consistent nor necessarily the right way to do things. Jots Open Qsys. Follow this post. Went for Nios II classic, used Nios/e (no Hardware multiplication, as the target device doesn&#8217;t have it. [...]]]></description>
			<content:encoded><![CDATA[<h3>About this post</h3>
<p>These are things I wrote down at different stages of introducing myself to Nios II and its environment. Nothing really consistent nor necessarily the right way to do things.</p>
<h3>Jots</h3>
<ul>
<li>Open Qsys. Follow <a href="http://www.rte.se/blog/blogg-modesty-corex/designing-our-own-nios-ii-system/3.5" target="_blank">this post</a>.</li>
<li>Went for Nios II classic, used Nios/e (no Hardware multiplication, as the target device doesn&#8217;t have it. Set instruction cache to 2 kB, and no data cache</li>
<li>Add 16 kB on-chip memory (Basic &gt; On-Chip Memory &gt; On-Chip Memory (RAM or ROM) ). Data width 32 bits, set hex file to raminit.hex (to be found at verilog/raminit.hex)</li>
<li>Attach memory to processor&#8217;s Avalon master</li>
<li>Attach peripherals</li>
<li>Connect clk_0&#8242;s clock output to all clock inputs (including processor&#8217;s).</li>
<li>Same with reset</li>
<li>Assign base addresses automatically: System &gt; Assign Base Addresses</li>
<li>Enter the CPU configuration, and assign the Reset and Exception Vectors to the onchip memory (this issues an offset to the addresses, per the peripheral&#8217;s offsets).</li>
<li>Build the Qsys project. Among all (Verilog) files, it generates a processor.sopcinfo file.</li>
</ul>
<h3>Software</h3>
<ul>
<li>Launch Nios II Software Build Tools for Eclipse (from Qsys or Quartus)</li>
<li>Pick a path for the workspace</li>
<li>Pick File &gt; New &gt; Nios II Application and BSP from Template. Assign the SOPC information file as processor.sopcinfo as generated before, and pick the &#8220;Hello World&#8221; template. There&#8217;s also a much smaller &#8220;Minimal Hello World&#8221; which allows communication with the JTAG UART.</li>
<li>Build the project. Eh, it failed. Not enough memory (printf is heavy. There&#8217;s a thinner version, but doesn&#8217;t matter now)</li>
<li>Go back to Qsys, and make on-chip memory 40960 bytes large (40kB, fitter fails if it&#8217;s 48 kB). Re-run Assign Base Addresses.</li>
<li>Build the Qsys project again</li>
<li>Regenerate the BSP: In Eclipse, right-click the BSP project, pick Nios II &gt; Generate BSP (NOT from the top menu&#8217;s Nios II, there is no such option there!). Or alternatively, within a NIOS2 shell (see below), and from the BSP project&#8217;s home directory, go
<pre>nios2-bsp-generate-files --settings settings.bsp --bsp-dir .</pre>
</li>
<li>Rebuild: Project &gt; Clean&#8230;  and clean all, with the rebuild option set.</li>
<li>To add a lot of files to a project: Right-click the project, pick Import&#8230;, General &gt; File System. Click Browse&#8230; and navigate to the directory where the files are and pick the <strong>directory</strong>. Then choose the desired files. Pick Advanced below, and pick &#8220;Add links&#8221; (it works).</li>
<li>To add an existing file to the project: Right-click the project, New &gt; File &gt; Advanced, check &#8220;Link to file in the file system&#8221; and pick the file. Then right-click the file (or several files) and pick &#8220;Add to Nios II build&#8221;</li>
<li>To remove a file, first right-click it, and pick &#8220;Remove from Nios II build&#8221;. Then right-click and delete. Failing to remove the file first will make the build system continue to look for it.</li>
<li>Creating a new application, based upon an existing BSP, and including the relevant source file sets it all up.</li>
<li>To compile manually, right-click the project, go to Nios &gt; Nios command shell&#8230; (that opens a shell window) and type &#8220;make&#8221;</li>
<li>It&#8217;s also possible to copy the relevant elements in the PATH variable, and compile with &#8220;make&#8221; outside this shell window. Or set up the environment, as shown <a href="http://billauer.co.il/blog/2017/06/quartus-path-env/" target="_blank">here</a>.</li>
<li>I had a stubborn linking error with alt_main.c having an undefined reference to &#8216;main&#8217; because I didn&#8217;t read my own note above about how to add a file to a project. It turned out that the Makefile doesn&#8217;t include any of the C source files (C_SRCS assigned to nothing in the Makefile). I ended up adding these entries manually. That allowed at least a manual build with the command shell, as mentioned in the bullet above.</li>
<li>The Eclipse project seems to consists of the Makefile, the .cproject XML file containing mostly useless mumbo-jumbo, and the .project XML file, which contains information about source files and build targets. There&#8217;s also .settings/language.settings.xml, which also seems not to contain anything relevant.</li>
<li>When creating a custom component, and an interrupt is required, be sure to associate the interrupt sender interface with an &#8220;Associated Addressable Interface&#8221; (e.g. associatedAddressablePoint set to avalon_slave_0 in the component&#8217;s tcl file). Otherwise, the interrupt will no be assigned an entry nor controller, so *_IRQ  and *_IRQ_INTERRUPT_CONTROLLER_ID  end up assigned with -1 in system.h.</li>
<li>For a shell prompt (&#8220;NIOS2 shell&#8221;) with all paths set up properly, go e.g.
<pre>/bulk/software/altera/lite-15.1/nios2eds/nios2_command_shell.sh</pre>
</li>
</ul>
<h3>Running against hardware</h3>
<p>Note: Quartus&#8217; programmer and the &#8220;Run&#8221; environment on Eclipse are mutually exclusive, competing for the USB bitblaster.</p>
<ul>
<li>Make sure you&#8217;ve quit Quartus&#8217; programmer (actually not necessary. Just be sure that the blue LED on the USB Blaster is off).</li>
<li>Also make sure to &#8220;terminate launch&#8221; on the Eclipse side before attempting to reprogram the FPGA (pressing the red stop-like button on the Nios Console is enough.</li>
<li>Pick the &#8220;hello&#8221; project (that is, not the BSP) and go to top menu: Run &gt; Run configurations&#8230;, pick Target Connection tab. Both a processor and a byte stream device should be enlisted (the latter is the jtaguart). Refresh to make sure it&#8217;s actually there.</li>
<li>If it says &#8220;Connected system ID hash not found on target at the expected base address&#8221; at the top, select &#8220;Ignore mismatched system ID&#8221; and &#8220;Ignore mismatched system timestamp&#8221;. This happens when there&#8217;s no system ID peripheral in the Qsys design.</li>
<li>The &#8220;Hello world from NIOS!!&#8221; should appear in the Nios II console</li>
<li>The base addresses etc. are listed in system.h inside the BSP (hello_bsp in my case).</li>
<li>This program printed out &#8220;Hello world&#8221; as well as blinked the LEDs:
<pre>#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;
#include &lt;io.h&gt;
#include &lt;system.h&gt;
#include &lt;altera_avalon_pio_regs.h&gt;

int main()
{
  int i;

  printf("Hello from Nios II!\n");

  while (1) {
    IOWR_ALTERA_AVALON_PIO_DATA(PIO_BASE, ((-i) &amp; 7));
    i++;
    usleep(100000);
  }
  return 0;
}</pre>
</li>
<li>To generate a hex file, right-click the project (&#8220;hello&#8221;) and pick Make Targets &gt; Build&#8230;, chooise mem_init_generate and click the Build button. The juicy part in the process was
<pre>elf2hex hello.elf 0x00010000 0x00019fff --width=32 --little-endian-mem --create-lanes=0 mem_init/raminit.hex</pre>
</li>
<li>Alternatively, go (skip to the &#8220;make&#8221; statement if already in a NIOS shell)
<pre>/path/to/altera/15.1/nios2eds/nios2_command_shell.sh <strong>make mem_init_generate</strong></pre>
</li>
<li>It noteworthy that the tools spotted my choice of the file name, even though it&#8217;s not located where Quartus expects it.</li>
<li>Giving the hex file to Quartus resulted in a lot of lines saying
<pre>Warning (113015): Width of data items in "raminit.hex" is greater than the memory width. Wrapping data items to subsequent addresses. Found 1280 warnings, reporting 10
    Warning (113009): Data at line (2) of memory initialization file "raminit.hex" is too wide to fit in one memory word. Wrapping data to subsequent addresses.
    Warning (113009): Data at line (3) of memory initialization file "raminit.hex" is too wide to fit in one memory word. Wrapping data to subsequent addresses.
    Warning (113009): Data at line (4) of memory initialization file "raminit.hex" is too wide to fit in one memory word. Wrapping data to subsequent addresses.</pre>
<p>etc.<br />
But this is most probably OK, as the processor worked immediately after FPGA configuration.</li>
<li><strong>Redirect printf() and other stdout to UART</strong>: By default, the standard output goes to the JTAG UART. To change this, right-click the BSP project, pick Nios II &gt; BSP Editor. Pick the &#8220;Main&#8221; tab, navigate to &#8220;hal &gt; common&#8221; (it usually starts there anyhow)  and change the stdout target to the desired UART. And regenerate the BSP.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://billauer.co.il/blog/2017/06/intel-fpga-nios-jots/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Remote Update from ECPQ flash on Altera Cyclone IV</title>
		<link>http://billauer.co.il/blog/2017/06/remote-update-intel-fpga-cyclone-iv/</link>
		<comments>http://billauer.co.il/blog/2017/06/remote-update-intel-fpga-cyclone-iv/#comments</comments>
		<pubDate>Sat, 03 Jun 2017 06:29:36 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[Altera]]></category>
		<category><![CDATA[FPGA]]></category>

		<guid isPermaLink="false">http://billauer.co.il/blog/?p=5237</guid>
		<description><![CDATA[Introduction This post relates to Altera (or should I say Intel FPGA?) Cyclone IV FPGAs loaded from an ECPQ flash in Active Serial x 1 (AS x 1) mode. Things written below are probably relevant to other Altera FPGAs as well, but keep in mind that Cyclone IV FPGAs have several peculiarities you won&#8217;t find [...]]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p>This post relates to Altera (or should I say Intel FPGA?) Cyclone IV FPGAs loaded from an ECPQ flash in Active Serial x 1 (AS x 1) mode. Things written below are probably relevant to other Altera FPGAs as well, but keep in mind that Cyclone IV FPGAs have several peculiarities you won&#8217;t find on other Altera device families.</p>
<p>&#8220;Remote Update&#8221; is the feature in some Altera FPGAs, which allows application logic / software to safely update the bitstream from which the FPGA is loaded. The trick is to always have a Factory (&#8220;Golden&#8221;) bitstream image on the flash, and update the &#8220;Application&#8221; image only. When powers goes up, the FPGA ends up with the Application bitstream if it&#8217;s OK, or the Factory bitstream if it&#8217;s absent or corrupt.</p>
<p>Since the bitstreams carry a CRC, it&#8217;s guaranteed that only valid bitstreams are used. It&#8217;s therefore safe to overwrite a previous Application bitstream image: If something goes wrong in the middle of writing, it won&#8217;t be deemed a valid bitstream, so the FPGA will end up with the Factory bitstream.</p>
<h3>The basics</h3>
<p>To implement a remote update feature on an FPGA design, there are two functional elements needed:</p>
<ul>
<li>The ability to write data into the configuration flash with user-designed logic / software. This is discussed in <a href="http://billauer.co.il/blog/2017/04/altera-ecpq-active-serial-nios/" target="_blank">this post</a>.</li>
<li>The logic / software that makes sure the FPGA ends up with the right  configuration (and, in particular, prevents an endless configuration  loop as explained next)</li>
</ul>
<p>Note that the Remote Update IP Core has nothing to do with flash  programming: Its function is merely to allow the FPGA&#8217;s logic to issue a  reconfiguration, and offer some information on how and why the current  bitstream was loaded.</p>
<p>When an FPGA powers up, it always configures from a constant address of the flash, which is zero on ECPQ flashes. In other words, the FPGA always powers up from the Factory bitstream, no matter what. It&#8217;s the user application logic / software&#8217;s duty to force the configuration of the Application bitstream when adequate. This means that during normal operation, there are always two configurations of the FPGA at powerup, one for the Factory bitstream, and one for the Application. This doubles the configuration time, of course.</p>
<p>How it happens: The FPGA is powered up, and loads the Factory bitstream from a fixed address. Through the Remote Update IP Core, the logic / software  in the FPGA sets the address of the Application image at the flash, from which the FPGA should configure itself. It then can triggers a reconfiguration of the FPGA.</p>
<p>The FPGA&#8217;s configuration state machine attempts to load a bitstream from the flash at the given address. If the bitstream&#8217;s magic words are in place and the CRC is OK, it starts running on the new bitstream. If not, it loads the Factory bitstream again as a fallback.</p>
<p>By virtue of a register of the Remote Update IP Core, the software / logic in the Factory bitstream detects that it was loaded due to a failure, and takes action (or no action) accordingly. It may try another address at the flash, or refrain from another reconfiguration altogether (i.e. stay with the &#8220;Golden Image&#8221;). The decision depends on the design requirements, but the crucial point here is to prevent an endless loop of configurations.</p>
<h3>Some reading</h3>
<p>This post is not a user guide or a substitute for these two must-read documents:</p>
<ul>
<li><a href="https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/hb/cyclone-iv/cyiv-51008.pdf" target="_blank">Chapter 8</a> in the Cyclone IV device  handbook, volume 1</li>
<li><a href="https://www.altera.com/literature/ug/ug_altremote.pdf" target="_blank">Altera Remote Update IP Core User Guide</a></li>
</ul>
<h3>Spoiler</h3>
<p>This Nios II code implements the loading of the Application bitstream. It written so it can be used on any bitstream, as is does nothing when run from an Application bitstream. It&#8217;s also safe for use with JTAG configuration (it won&#8217;t issue a reconfiguration in that case).</p>
<pre>void do_remote_update(void) {
  alt_u32 app_bitstream_addr = 0x100000;

  alt_u32 mode = IORD_32DIRECT(REMOTE_UPDATE_0_BASE, 0) &amp; 3;
  alt_u32 config_reason = IORD_32DIRECT(REMOTE_UPDATE_0_BASE, 0x64);

  if ((mode == 0) &amp;&amp; (config_reason == 0)) {
    IOWR_32DIRECT(REMOTE_UPDATE_0_BASE, 0x30, 0); // Turn off watchdog
    IOWR_32DIRECT(REMOTE_UPDATE_0_BASE, 0x40, app_bitstream_addr);

    IOWR_32DIRECT(REMOTE_UPDATE_0_BASE, 0x74, 1); // Trigger reconfiguration

    while (1); // Wait briefly until configuration takes place
  }
}</pre>
<p>do_remote_update() should be called first thing in the Nios II code entry. If the function returns, the FPGA is either running on the Application bitstream, or the Factory (&#8220;Golden&#8221;) bitstream with a good reason not to reconfigure (i.e. a previous failure to load the Application bitstream or after a JTAG bitstream load).</p>
<p>Please refer to the &#8220;Programming the flash with NIOS software&#8221; section in <a href="http://billauer.co.il/blog/2017/04/altera-ecpq-active-serial-nios/" target="_blank">this post</a> on how to generate the image of the Application bitstream.</p>
<p>The cod above works with the following setting:</p>
<ul>
<li>The FPGA&#8217;s NCONFIG pin is tied high. This will not work if the NCONFIG pin is driven by some power supply watch logic or alike, because config_reason won&#8217;t be zero if NCONFIG triggered the configuration.</li>
<li>REMOTE_UPDATE_0_BASE is the base address in NIOS&#8217; address space of a Remote Update IP core, <strong>which has the &#8220;writing configuration parameters&#8221; option enabled.</strong></li>
<li>The application bitstream image is loaded at flash address 0x100000 (i.e. can be read with epcs_read_buffer() using this address)</li>
<li>The Golden image is at address zero, of course.</li>
</ul>
<p>If loading the application image fails once, no other attempts are made. This is the straightforward thing to do if there&#8217;s no additional image to try from. There&#8217;s no sensible reason to try the same image again, unless the PCB designer has done a really bad job.</p>
<p>How this function works, briefly:</p>
<ul>
<li>It verifies that the configuration mode is 0, that is Factory mode. If we&#8217;re in Application mode, the function returns.</li>
<li>It verifies that the trigger for configuration was a powerup by checking config_reason, or it returns. This prevents an endless loop of configurations in the case of a fallback into the Factory bitstream in the event of a failed attempt to load the Application bitstream.<br />
Note that if the configuration was triggered as a result of an assertion of the FPGA&#8217;s NCONFIG pin, or on a JTAG configuration, config_reason will read 0x10.</li>
<li>The watchdog is disabled, so the Application bitstream doesn&#8217;t have to deal with it</li>
<li>The Application bitstream&#8217;s address is set</li>
<li>A configuration is forced by writing to the dedicated register</li>
<li>An endless while (1) loop is invoked for preventing the execution to go on &#8212; not that it would go anywhere far.</li>
</ul>
<h3>General notes</h3>
<ul>
<li>It&#8217;s important to observe that the terminology of Factory / Application  configuration modes, which is used in the docs, isn&#8217;t just for the sake  of clarity: The Remote Update IP Core exposes different registers, based  upon whether it considers itself to be in either of the modes: In  particular, when in Application mode, there is very little the logic can  do, except for jumping back to Factory mode or to reset the watchdog.</li>
<li>When generating the Remote Update block (most likely in Qsys), be sure to check &#8220;Add support for writing configuration parameters&#8221;. Or you&#8217;ll keep wondering why writing to the NIOS registers has no effect at all.</li>
<li>Also be sure to set configuration mode to remote for the FPGA project. There should be a line as follows in the QSF file:
<pre>set_global_assignment -name STRATIXIII_UPDATE_MODE REMOTE</pre>
</li>
<li>When setting the boot address register, use the actual boot address with the two LSBs forced to zero. When it&#8217;s read back after a configuration as the previous boot address, it&#8217;s shifted two bits to the left. The docs are a bit confusing about this too. Go figure.</li>
<li>The watchdog is enabled by default, so unless it&#8217;s tended to in the application bitstream, it must be explicitly turned off before firing off reconfiguration.</li>
<li>The watchdog timer runs on the internal configuration clock, which is 10 MHz unless the external CLKUSR is applied..</li>
</ul>
<h3>Accessing registers</h3>
<p>Put short, the registers map is a mess. Out of the long list given in Tables 20 and 21 in the <a href="https://www.altera.com/literature/ug/ug_altremote.pdf" target="_blank">Remote Update IP Core User Guide</a>, only a handful have a meaning.</p>
<p>It&#8217;s important to realize that some registers are valid when the Remote Update IP core is in Factory mode, and others when it&#8217;s in Application mode. These two register sets are mutually exclusive (except for the CURRENT_STATE_MODE register). The test program shown further down this post demonstrates which registers are valid in each mode.</p>
<p>This is a list of things to keep in mind regarding these registers:</p>
<ul>
<li>Reading from a Factory mode register in Application mode (and vice versa) returns meaningless (and rather confusing) data.</li>
<li>The way to make sense of the registers from the docs is to refer to tables 16 and 17 in the <a href="https://www.altera.com/literature/ug/ug_altremote.pdf" target="_blank">Remote Update IP Core User Guide</a> to tell what you want to access in terms of which param and which  read_source, and then find the address for them in table 21. Several  registers in table 21 constitute combinations of param and read_source  that aren&#8217;t listed in table 17, which probably renders them meaningless.</li>
<li>&#8230; except for RU_RESET_TIMER and RU_RECONFIG, which are interpreted  in logic to generate a reset signal / reconfiguration signal  respectively, and and therefore not listed in table 17.</li>
<li>Too add more confusion, readbacks don&#8217;t work as one might expect.  For example, the boot address for the next configuration is set at  address offset 0x40, but reading back from the same address always  yields the factory boot address. To get the boot address for the next  configuration (i.e. the one written to 0x40), read it back at 0x4c.</li>
<li>More confusion: The translation from the param numbers to the Nios  access register isn&#8217;t some arithmetic operation, but rather some lookup  logic of the avl_controller_cycloneiii_iv module in  Qsys_remote_update_0_remote_update_controller.sv, which is generated  automatically by Qsys.</li>
<li>The registers listed in the BSP&#8217;s drivers/inc/altera_remote_update_regs.h are those of all Altera FPGAs <strong>except </strong>Cyclone IV. For example, the docs as well as the Qsys Verilog file () place RU_WATCHDOG_TIMEOUT at address 0x08 (actually, addresses 0x08-0x0b) but the BSP&#8217;s altera_remote_update_regs.h</li>
<li>Note that compared with other FPGA families, Cyclone IV&#8217;s register interface is considerably more extensive, allowing the controller to query the status of two configuration cycles back in history. Seems like this feature was dropped on later FPGAs (due to lack of interest vs complication&#8230;?)</li>
</ul>
<h3>The RU_RECONFIG_TRIGGER_CONDITIONS register</h3>
<p>This register is interesting in particular, as it tells us why that caused the FPGA to configure the bitstream that is currently running:</p>
<pre>IORD_32DIRECT(REMOTE_UPDATE_0_BASE, 0x64); // Register 0x19 in the guide</pre>
<p>And to obtain the reason for the configuration before that:</p>
<pre>IORD_32DIRECT(REMOTE_UPDATE_0_BASE, 0x68); // Register 0x1a in the guide</pre>
<p>These read the remote config core&#8217;s param 3&#8242;b111 with read source 2&#8242;b01 and 2&#8242;b10 respectively. Note that the translation from the param number of 3&#8242;b111 to the Nios access register isn&#8217;t just a multiplication, but rather some lookup logic as mentioned (but not detailed) above.</p>
<p>Running some tests of my own (with the test program below), I got the following values. There&#8217;s nothing surprising about these results; they are exactly as documented.</p>
<ul>
<li>On cold configuration: <strong>0</strong></li>
<li>When not disabling the watchdog (not handling it after configuration): <strong>2</strong> (bit 1 set, User watchdog timer timeout)</li>
<li>After failed application configuration due to lack of image: <strong>4</strong> (bit 2 set, nSTATUS  asserted by an external device as  the result of an error)</li>
<li>After failed application configuration due to damaged image: <strong>8</strong> (bit 3 set, CRC  error during application configuration)</li>
<li>On configuration from JTAG; <strong>0x10</strong> (bit 4 set, External  configuration reset (nCONFIG)  assertion)</li>
</ul>
<h3>A test program</h3>
<p>On my way to understanding how the whole thing works, I wrote a small test program that ran on the Nios II processor, which dumps all registers that are relevant for each mode. As a bonus, it can be used as a register reference, as it lists all registers available for reading Factory vs. Application mode in the respective structures.</p>
<pre>#include &lt;system.h&gt;
#include &lt;alt_types.h&gt;
#include &lt;io.h&gt;
#include "sys/alt_stdio.h"
#include &lt;unistd.h&gt;

int main()
{
  int mode;

  struct regitem {
    int read_source;
    int param;
    const char *desc;
  };

  const struct regitem factoryparams[] = {
    { 0, 0x00, "Current Machine State Mode" },
    { 0, 0x10, "Factory Boot Address" },
    { 1, 0x10, "Previous Boot Address" },
    { 1, 0x18, "Previous reconfiguration trigger source" },
    { 2, 0x10, "One before previous Boot Address" },
    { 2, 0x18, "One before previous reconfiguration trigger source" },
    { 3, 0x04, "Early confdone check bits" },
    { 3, 0x08, "Watchdog timeout value" },
    { 3, 0x0c, "Watchdog enable bit" },
    { 3, 0x10, "Boot address" },
    { 3, 0x14, "Force internal oscillator" },
    {}
  };

  const struct regitem applicationparams[] = {
    { 0, 0x00, "Current Machine State Mode" },
    { 1, 0x08, "Watchdog timeout value" },
    { 1, 0x0c, "Watchdog enable bit" },
    { 2, 0x10, "Boot address" },
    {}
  };

  const struct regitem unknownparams[] = { {} };

  const struct {
    const struct regitem *list;
    char *desc;
  } modetab[4] = {
    { factoryparams, "Factory mode" },
    { applicationparams, "Application mode" },
    { applicationparams, "Application mode with watchdog enabled" },
    { unknownparams, "Unknown mode" },
  };

  const struct regitem *item;

  alt_putstr("\r\n----------------   BASE IMAGE   ---------------------\r\n\r\n");

  mode = IORD_32DIRECT(REMOTE_UPDATE_0_BASE, 0) &amp; 3;

  alt_printf("Remote update register dump\r\nMode: %s\r\n",
	     modetab[mode].desc);

  alt_putstr("\r\nParameters:\r\n");

  for (item = modetab[mode].list; item-&gt;desc; item++) {
    int addr = (item-&gt;param + item-&gt;read_source) * 4;
    alt_printf("%s (0x%x) = 0x%x\r\n", item-&gt;desc, addr,
	       IORD_32DIRECT(REMOTE_UPDATE_0_BASE, addr));
  }

  if (mode == 0) { // Factory mode only
    usleep(500000);
    IOWR_32DIRECT(REMOTE_UPDATE_0_BASE, 0x30, 0); // Turn off watchdog
    IOWR_32DIRECT(REMOTE_UPDATE_0_BASE, 0x40, 0x100000);
    IOWR_32DIRECT(REMOTE_UPDATE_0_BASE, 0x74, 1);
  }

  /* Event loop never exits. */
  while (1);

  return 0;
}</pre>
<h3>Tests results</h3>
<p>The test program above was compiled and included in the bitstream that was loaded into flash address 0 (Factory image).</p>
<p>The first alt_putstr was then changed to say &#8220;Application Image&#8221;, and the compiled version of that was included in the bitstream loaded at address 0x100000 of the flash (Application Image).</p>
<p>Standard output was directed to a physical UART (instead of the JTAG UART) for the purpose of this test (Eclipse&#8217;s JTAG UART console didn&#8217;t like these games with configurations).</p>
<p><strong>And then I powered on:</strong></p>
<pre>----------------   BASE IMAGE   ---------------------

Remote update register dump
Mode: Factory mode

Parameters:
Current Machine State Mode (0x0) = 0x0
Factory Boot Address (0x40) = 0x0
Previous Boot Address (0x44) = 0xc
Previous reconfiguration trigger source (0x64) = 0x0
One before previous Boot Address (0x48) = 0xc
One before previous reconfiguration trigger source (0x68) = 0x0
Early confdone check bits (0x1c) = 0x1
Watchdog timeout value (0x2c) = 0x0
Watchdog enable bit (0x3c) = 0x1
Boot address (0x4c) = 0x0
Force internal oscillator (0x5c) = 0x1

----------------   APPLICATION IMAGE   ---------------------

Remote update register dump
Mode: Application mode

Parameters:
Current Machine State Mode (0x0) = 0x1
Watchdog timeout value (0x24) = 0x1ffe0008
Watchdog enable bit (0x34) = 0x0
Boot address (0x48) = 0x400000</pre>
<p>Note that if the register writes in the example are done <strong>before</strong> showing the registers, these following two lines would replace their respective outputs in the Base Image parameter list:</p>
<pre>Watchdog enable bit (0x3c) = 0x0
Boot address (0x4c) = 0x100000</pre>
<p><strong>The same, with the application image wiped out (zeros):</strong></p>
<pre>----------------   BASE IMAGE   ---------------------

Remote update register dump
Mode: Factory mode

Parameters:
Current Machine State Mode (0x0) = 0x0
Factory Boot Address (0x40) = 0x0
Previous Boot Address (0x44) = 0xc
Previous reconfiguration trigger source (0x64) = 0x0
One before previous Boot Address (0x48) = 0xc
One before previous reconfiguration trigger source (0x68) = 0x0
Early confdone check bits (0x1c) = 0x1
Watchdog timeout value (0x2c) = 0x0
Watchdog enable bit (0x3c) = 0x1
Boot address (0x4c) = 0x0
Force internal oscillator (0x5c) = 0x1

----------------   BASE IMAGE   ---------------------

Remote update register dump
Mode: Factory mode

Parameters:
Current Machine State Mode (0x0) = 0x0
Factory Boot Address (0x40) = 0x0
Previous Boot Address (0x44) = 0x400000
Previous reconfiguration trigger source (0x64) = 0x4
One before previous Boot Address (0x48) = 0xc
One before previous reconfiguration trigger source (0x68) = 0x0
Early confdone check bits (0x1c) = 0x1
Watchdog timeout value (0x2c) = 0x0
Watchdog enable bit (0x3c) = 0x1
Boot address (0x4c) = 0x0
Force internal oscillator (0x5c) = 0x1

----------------   BASE IMAGE   ---------------------

Remote update register dump
Mode: Factory mode

Parameters:
Current Machine State Mode (0x0) = 0x0
Factory Boot Address (0x40) = 0x0
Previous Boot Address (0x44) = 0x400000
Previous reconfiguration trigger source (0x64) = 0x4
One before previous Boot Address (0x48) = 0x400000
One before previous reconfiguration trigger source (0x68) = 0x4
Early confdone check bits (0x1c) = 0x1
Watchdog timeout value (0x2c) = 0x0
Watchdog enable bit (0x3c) = 0x1
Boot address (0x4c) = 0x0
Force internal oscillator (0x5c) = 0x1

<em><span style="color: #888888;">[ ... etc ... ]</span></em></pre>
<p><strong>The same, with the Application image loaded in place, but with a small error (changed a single bit):</strong></p>
<p>(this caused a CRC error)</p>
<pre>----------------   BASE IMAGE   ---------------------

Remote update register dump
Mode: Factory mode

Parameters:
Current Machine State Mode (0x0) = 0x0
Factory Boot Address (0x40) = 0x0
Previous Boot Address (0x44) = 0xc
Previous reconfiguration trigger source (0x64) = 0x0
One before previous Boot Address (0x48) = 0xc
One before previous reconfiguration trigger source (0x68) = 0x0
Early confdone check bits (0x1c) = 0x1
Watchdog timeout value (0x2c) = 0x0
Watchdog enable bit (0x3c) = 0x1
Boot address (0x4c) = 0x0
Force internal oscillator (0x5c) = 0x1

----------------   BASE IMAGE   ---------------------

Remote update register dump
Mode: Factory mode

Parameters:
Current Machine State Mode (0x0) = 0x0
Factory Boot Address (0x40) = 0x0
Previous Boot Address (0x44) = 0x400000
Previous reconfiguration trigger source (0x64) = 0x8
One before previous Boot Address (0x48) = 0xc
One before previous reconfiguration trigger source (0x68) = 0x0
Early confdone check bits (0x1c) = 0x1
Watchdog timeout value (0x2c) = 0x0
Watchdog enable bit (0x3c) = 0x1
Boot address (0x4c) = 0x0
Force internal oscillator (0x5c) = 0x1

----------------   BASE IMAGE   ---------------------

Remote update register dump
Mode: Factory mode

Parameters:
Current Machine State Mode (0x0) = 0x0
Factory Boot Address (0x40) = 0x0
Previous Boot Address (0x44) = 0x400000
Previous reconfiguration trigger source (0x64) = 0x8
One before previous Boot Address (0x48) = 0x400000
One before previous reconfiguration trigger source (0x68) = 0x8
Early confdone check bits (0x1c) = 0x1
Watchdog timeout value (0x2c) = 0x0
Watchdog enable bit (0x3c) = 0x1
Boot address (0x4c) = 0x0
Force internal oscillator (0x5c) = 0x1

<em><span style="color: #888888;">[ ... etc ... ]</span></em></pre>
<p><strong>Loading with JTAG:</strong> I set up both flash images properly, powered up so the FPGA stayed on the Application Image. At that point, I loaded the SOF of the Factory bitstream into the FPGA through JTAG (with a USB Blaster). The JTAG operation yielded this:</p>
<pre>----------------   BASE IMAGE   ---------------------

Remote update register dump
Mode: Factory mode

Parameters:
Current Machine State Mode (0x0) = 0x0
Factory Boot Address (0x40) = 0x0
Previous Boot Address (0x44) = 0x400000
Previous reconfiguration trigger source (0x64) = 0x10
One before previous Boot Address (0x48) = 0xc
One before previous reconfiguration trigger source (0x68) = 0x0
Early confdone check bits (0x1c) = 0x1
Watchdog timeout value (0x2c) = 0x0
Watchdog enable bit (0x3c) = 0x1
Boot address (0x4c) = 0x0
Force internal oscillator (0x5c) = 0x1

----------------   APPLICATION IMAGE   ---------------------

Remote update register dump
Mode: Application mode

Parameters:
Current Machine State Mode (0x0) = 0x1
Watchdog timeout value (0x24) = 0x1ffe0008
Watchdog enable bit (0x34) = 0x0
Boot address (0x48) = 0x400000</pre>
<p>When loading the same bitstream through JTAG once again the same result is obtained, only with &#8220;One before previous reconfiguration trigger source&#8221; set to 0x10 as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://billauer.co.il/blog/2017/06/remote-update-intel-fpga-cyclone-iv/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quartus/Linux: Setting PATH and environment for command-line</title>
		<link>http://billauer.co.il/blog/2017/06/quartus-path-env/</link>
		<comments>http://billauer.co.il/blog/2017/06/quartus-path-env/#comments</comments>
		<pubDate>Fri, 02 Jun 2017 10:50:37 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[Altera]]></category>
		<category><![CDATA[FPGA]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://billauer.co.il/blog/?p=5235</guid>
		<description><![CDATA[The classic way: $ export QUARTUS_ROOTDIR=/path/to/altera/15.1/quartus $ . $QUARTUS_ROOTDIR/adm/qenv.sh Or open a shell (will set path, but not a full environment): $ /path/to/altera/15.1/nios2eds/nios2_command_shell.sh This is good for compiling for NIOS etc.]]></description>
			<content:encoded><![CDATA[<p>The classic way:</p>
<pre>$ export QUARTUS_ROOTDIR=/path/to/altera/15.1/quartus
$ . $QUARTUS_ROOTDIR/adm/qenv.sh</pre>
<p>Or open a shell (will set path, but not a full environment):</p>
<pre>$ /path/to/altera/15.1/nios2eds/nios2_command_shell.sh</pre>
<p>This is good for compiling for NIOS etc.</p>
]]></content:encoded>
			<wfw:commentRss>http://billauer.co.il/blog/2017/06/quartus-path-env/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VMplayer: Silencing excessive hard disk activity</title>
		<link>http://billauer.co.il/blog/2017/05/vmplayer-disk-calm/</link>
		<comments>http://billauer.co.il/blog/2017/05/vmplayer-disk-calm/#comments</comments>
		<pubDate>Tue, 30 May 2017 14:18:29 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[Virtualization]]></category>

		<guid isPermaLink="false">http://billauer.co.il/blog/?p=5231</guid>
		<description><![CDATA[For some unknown reason, possibly after an VMplayer upgrade, running any Windows Virtual machine on my Linux machine with WMware Player caused some non-stop heavy hard disk activity, even when the guest machine was effectively idle, and made had no I/O activity of its own. Except for being surprisingly annoying, it also made the mouse [...]]]></description>
			<content:encoded><![CDATA[<p>For some unknown reason, possibly after an VMplayer upgrade, running any Windows Virtual machine on my Linux machine with WMware Player caused some non-stop heavy hard disk activity, even when the guest machine was effectively idle, and made had no I/O activity of its own.</p>
<p>Except for being surprisingly annoying, it also made the mouse pointer non-responsive and the effect was adverse on the hosting machine as well.</p>
<div>
<p>So eventually I managed to get things normal by editing the virtual machine&#8217;s  .vmx file as described below.</p>
<p>I have Vmplayer 6.0.2 on Fedora 12 (suppose both are considered quite old).</p>
<p>Following <a href="https://artykul8.com/2012/06/vmware-performance-enhancing/" target="_blank">this post</a>, add</p>
<pre>isolation.tools.unity.disable = "TRUE"
unity.allowCompositingInGuest = "FALSE"
unity.enableLaunchMenu = "FALSE"
unity.showBadges = "FALSE"
unity.showBorders = "FALSE"
unity.wasCapable = "FALSE"</pre>
<p>(unity.wasCapable was already in the file, so remove it first)</p>
<p>That appeared to help somewhat. But what really gave the punch was also adding</p>
<pre>MemTrimRate = "0"
sched.mem.pshare.enable = "FALSE"
MemAllowAutoScaleDown = "FALSE"</pre>
<p>Don&#8217;t ask me what it means. Your guess is as good as mine.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://billauer.co.il/blog/2017/05/vmplayer-disk-calm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux: Where the USB related kernel files are</title>
		<link>http://billauer.co.il/blog/2017/05/linux-usb-files/</link>
		<comments>http://billauer.co.il/blog/2017/05/linux-usb-files/#comments</comments>
		<pubDate>Wed, 17 May 2017 08:51:40 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Linux kernel]]></category>
		<category><![CDATA[USB]]></category>

		<guid isPermaLink="false">http://billauer.co.il/blog/?p=5221</guid>
		<description><![CDATA[A few notes on where to find USB related kernel files on a Linux system (kernel 3.12.20 in my case) $ lsusb [ ... ] Bus 001 Device 059: ID 046d:c52b Logitech, Inc. Now find the position in the tree. It should be device 59 under bus number 1: $ lsusb -t [ ... ] [...]]]></description>
			<content:encoded><![CDATA[<p>A few notes on where to find USB related kernel files on a Linux system (kernel 3.12.20 in my case)</p>
<pre>$ lsusb
[ ... ]
Bus 001 Device 059: ID 046d:c52b Logitech, Inc.</pre>
<p>Now find the position in the tree. It should be device 59 under bus number 1:</p>
<pre>$ lsusb -t
[ ... ]
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/6p, 480M
    |__ Port 4: Dev 4, If 0, Class=hub, Driver=hub/4p, 480M
        |__ Port 1: Dev 59, If 0, Class=HID, Driver=usbhid, 12M
        |__ Port 1: Dev 59, If 1, Class=HID, Driver=usbhid, 12M
        |__ Port 1: Dev 59, If 2, Class=HID, Driver=usbhid, 12M
        |__ Port 3: Dev 98, If 0, Class=vend., Driver=pl2303, 12M
    |__ Port 6: Dev 94, If 0, Class=vend., Driver=rt2800usb, 480M</pre>
<p>So it&#8217;s bus 1, hub on power 4 and then port 1. Verify by checking the IDs:</p>
<pre>$ cat /sys/bus/usb/devices/usb1/1-4/1-4.1/idVendor
046d
$ cat /sys/bus/usb/devices/usb1/1-4/1-4.1/idProduct
c52b</pre>
<p>or look at the individual interfaces:</p>
<pre>$ cat /sys/bus/usb/devices/usb1/1-4/1-4.1/1-4.1\:1.2/bInterfaceClass
03</pre>
<p>The device file accessed for raw userspace I/O with a USB device (with e.g libusb) is in /dev/usb/ followed by the bus number and address. For example, the Logitech device mentioned above is at bus 1, address 59, hence</p>
<pre>$ ls -l /dev/bus/usb/001/059
crw-rw-r-- 1 root root 189, 58 2017-05-17 09:57 /dev/bus/usb/001/059</pre>
<p>Note the permissions and major/minors. The major is 189 (usb_devices on my system, according to /proc/devices). The minor is the ((bus_number-1) * 128) + address &#8211; 1.</p>
<p>The permissions and ownership are those in effect for who&#8217;s allowed to access this device. This is the place to check if udev rules that allow wider access to a device have done their job.</p>
]]></content:encoded>
			<wfw:commentRss>http://billauer.co.il/blog/2017/05/linux-usb-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Altera ECPQ flash access with a Nios II processor + programming bitfiles</title>
		<link>http://billauer.co.il/blog/2017/04/altera-ecpq-active-serial-nios/</link>
		<comments>http://billauer.co.il/blog/2017/04/altera-ecpq-active-serial-nios/#comments</comments>
		<pubDate>Sun, 23 Apr 2017 16:56:02 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[Altera]]></category>
		<category><![CDATA[FPGA]]></category>

		<guid isPermaLink="false">http://billauer.co.il/blog/?p=5207</guid>
		<description><![CDATA[Introduction This post outlines some technical details on accessing an Altera ECPQ flash from a Nios II processor for read, write and erase. A non-OS settings (&#8220;bare metal&#8221;) setting is assumed. And as a bonus (at the bottom of this post), how to program the flash based upon a SOF file, both with JTAG and [...]]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p>This post outlines some technical details on accessing an Altera ECPQ flash from a Nios II processor for read, write and erase. A non-OS settings (&#8220;bare metal&#8221;) setting is assumed.</p>
<p>And as a bonus (at the bottom of this post), how to program the flash based upon a SOF file, both with JTAG and by writing directly.</p>
<p>Remote Update is discussed in <a title="Remote Update from ECPQ flash on Altera Cyclone IV" href="http://billauer.co.il/blog/2017/06/remote-update-intel-fpga-cyclone-iv/" target="_blank">this post</a>.</p>
<h3>Hardware setup</h3>
<p>In the Qsys project, there should be an instance of the Legacy EPCS/EPCQx1 Flash Controller, configured with the default parameters (not that there is much to configure). The peripheral&#8217;s epcs_control_port should be connected to the Nios II&#8217;s data master Avalon port (no point connecting it to the instruction master too).</p>
<p>In this example, we&#8217;ll assume that the name of Flash Controller in Qsys is epcs_flash_controller_0.</p>
<p>The interrupt signal isn&#8217;t used in the software setting given below, but as the connection to the Nios processor, as well as the interrupt number assignment is automatic, let it be.</p>
<p>Clock and reset &#8212; like the other peripherals.</p>
<p>The external conduit is connected as follows to an ECPQ flash, for a x1 access:</p>
<ul>
<li>Flash pin DATA0 to epcs_flash_controller_0_sdo (FPGA pin ASDO)</li>
<li>Flash pin DCLK to epcs_flash_controller_0_dclk (FPGA pin DCLK)</li>
<li>Flash pin nCS to epcs_flash_controller_0_sce (FPGA pin NCSO)</li>
<li>Flash pin DATA1 to epcs_flash_controller_0_data (FPGA pin DATA0)</li>
</ul>
<p>The FPGA pins above relate to dual-use of the configuration, which allows the FPGA to configure in Active Serial (AS) x 1 mode. Once the configuration is done, these pins become general-purpose I/O (when so required by assignments), which allows regular access to the flash device.</p>
<p>Note that the flash pin DATA1 is connected to the FPGA pin DATA0 &#8212; this is not a mistake, but the correct wiring for AS x 1 interface.</p>
<p>It&#8217;s of course possible to connect the flash to regular I/O pins, but then the FPGA won&#8217;t be able to configure from the flash.</p>
<h3>Software</h3>
<p>Altera&#8217;s BSP includes drivers for flash operations with multiple layers of abstraction. This abstraction is not always necessary, and makes it somewhat difficult to figure out what&#8217;s going on (in particular when things go wrong). In particular, the higher-level drivers erase flash sectors automatically before writing, which can render some counterintuitive behavior, for example if multiple write requests are made on the same sector.</p>
<p>I therefore prefer working with the lowest-level drivers, which merely translate the flash commands into SPI communication. It leaves the user with the responsibility to erase sectors before writing to them.</p>
<p>The rule is simple: The flash is divided into sectors of 64 kB each. An erase operation is performed on such 64 kB sector, leaving all its bytes in all-1&#8242;s (all bytes are 0xff).</p>
<p>Writing can then be done to arbitrary addresses, but effectively the data in the flash is the written data ANDed with the previous content of the memory cells. Which means a plain write, if the region has been previously erased. It&#8217;s commonly believed that it&#8217;s unhealthy for the flash to write to a byte cell twice without an erase in the middle.</p>
<p>This is a simple program that runs on the Nios II processor, which demonstrates read, write and erase.</p>
<pre>#include &lt;system.h&gt;
#include &lt;alt_types.h&gt;
#include &lt;io.h&gt;
#include "sys/alt_stdio.h"
#include "epcs_commands.h"

static void hexprint(alt_u8 *buf, int num) {
  int i;

  const char hexes[] = "0123456789abcdef";

  for (i = 0; i &lt; num; i++) {
    alt_putchar(hexes[(buf[i] &gt;&gt; 4) &amp; 0xf]);
    alt_putchar(hexes[buf[i] &amp; 0xf]);
    if ((i &amp; 0xf) == 0xf)
      alt_putchar(10); // "\n"
    else
      alt_putchar(32); // " "
  }
  alt_putchar(10); // "\n"
}

int main()
{
  alt_u32 register_base = EPCS_FLASH_CONTROLLER_0_BASE + EPCS_FLASH_CONTROLLER_0_REGISTER_OFFSET;
  alt_u32 silicon_id;

  alt_u8 buf[256];
  alt_u32 junk = 0x12345678;
  const alt_u32 flash_address = 0x100000;

  silicon_id = epcs_read_device_id(register_base);

  alt_printf("ID = %x\n", silicon_id);

  // epcs_read_buffer always returns the length of the buffer, so no
  // point checking its return value.

  alt_printf("Before doing anything:\n");

  epcs_read_buffer(register_base, flash_address, buf, sizeof(buf), 0);
  hexprint(buf, 16);

  // epcs_sector_erase erases the 64 kiB sector that contains the address
  // given as its second argument, and waits for the erasure to complete
  // by polling the status register and waiting for the WIP (write in progress)
  // bit to clear.

  epcs_sector_erase(register_base, flash_address, 0);

  alt_printf("After erasing\n");

  epcs_read_buffer(register_base, flash_address, buf, sizeof(buf), 0);
  hexprint(buf, 16);

  // epcs_write_buffer must be used on a region previously erased. The
  // command waits for the operation to complete by polling the status
  // register and waiting for the WIP (write in progress) bit to clear.
  epcs_write_buffer(register_base, flash_address, (void *) &amp;junk, sizeof(junk), 0);

  alt_printf("After writing\n");

  epcs_read_buffer(register_base, flash_address, buf, sizeof(buf), 0);
  hexprint(buf, 16);

  /* Event loop never exits. */

  while (1);

  return 0;
}</pre>
<p>The program reads 256 bytes each time, even though only 16 bytes are displayed. Any byte count is allowed in read and write. Needless to say, flash_address can be changed to any address in the device&#8217;s range. The choice of 0x100000 kept it off the configuration bitstream for the relevant FPGA.</p>
<p>This is the output of the program above running against an EPCQ16:</p>
<pre>ID = 20ba15
Before doing anything:
78 56 34 12 ff ff ff ff ff ff ff ff ff ff ff ff

After erasing
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

After writing
78 56 34 12 ff ff ff ff ff ff ff ff ff ff ff ff</pre>
<p>The data in the &#8220;Before doing anything&#8221; part can be anything that was left in the flash when the program ran. In the case above, it&#8217;s the results of the previous run of the same program.</p>
<p>As a side note, all EPCQ flashes also support erasing subsectors, each of 4 kiB size (hence 16 subsectors per sectors). Altera&#8217;s low-level drivers don&#8217;t support subsector erase, but it&#8217;s quite easy to expand the code to do so.</p>
<h3>Programming the flash with a SOF file</h3>
<p>As promised, here&#8217;s the outline of how to program the EPCQ flash with a bitstream configuration file. Not as fancy as the topic above, but nevertheless useful. The flash needs to be connected as follows:</p>
<ul>
<li>Flash pin DATA0 to FPGA pin ASDO</li>
<li>Flash pin DCLK to FPGA pin DCLK</li>
<li>Flash pin nCS to FPGA pin NCSO</li>
<li>Flash pin DATA1 to FPGA pin DATA0 (once again, this is not a mistake. DATA1 to DATA0 indeed)</li>
</ul>
<p>First thing first: Generate a JIC file. Command-line style, e.g.:</p>
<pre>quartus_cpf -c -d EPCQ16 -s EP4CE15 projname.sof projname.jic</pre>
<p>In the example above, the EPCQ16 argument is the flash device, and the EP4CE15 is the FPGA that will be used to program the flash, which is most likely the same FPGA the SOF targets.</p>
<p>Or do it with GUI:</p>
<ul>
<li>In Quartus, pick File &gt; Convert Programming  File&#8230;</li>
<li>Choose jic output file format, and set the output file name.</li>
<li>Set the configuration device to e.g. EPCQ16, Active Serial (not x4).</li>
<li>Pick the SOF Data  row, Page_0, click Add File&#8230; and pick SOF file.</li>
<li>Pick the Flash Loader  and click Add Device&#8230;, and choose e.g. Cyclone IV E, and then the same  device as listed for the SOF file.</li>
<li>If you want to write to the flash with your own utility, check “Create Config data RPD”</li>
<li>Click Generate. A window  saying the JIC file has been generated successfully should appear.</li>
<li>Click  Close to close this tool.</li>
</ul>
<p><strong>Programming the flash with JTAG:</strong></p>
<ul>
<li>Open the regular JTAG programmer in Quartus (not  the one in Eclipse). The one used to configure the FPGA via JTAG with a bitstream, that is.</li>
<li>Click Add File&#8230; and select the JIC file created above.</li>
<li>The  FPGA with its flash attached should appear in the diagram part of the window.</li>
<li>Select  the Program/Configure checkbox on the flash&#8217;  (e.g. EPCQ16) row</li>
<li>Click Start.</li>
<li>This  should take some 10 seconds or so (for EP4CE15&#8242;s bitfile), and end successfully.</li>
<li>The flash is  now programmed.</li>
</ul>
<p>Note that there&#8217;s an &#8220;Erase&#8221; checkbox on the flash&#8217; row &#8212; there is <strong>no</strong> need to enable it along with Program/Configure, and neither is it necessary. The Programmer gets the hint, and erases the flash before programming it.</p>
<p><strong>Programming the flash with NIOS software</strong> (or similar)</p>
<p>Note that I have <a title="Remote Update from ECPQ flash on Altera Cyclone IV" href="http://billauer.co.il/blog/2017/06/remote-update-intel-fpga-cyclone-iv/" target="_blank">another post</a> focusing on remote update.</p>
<p>To program the flash with your own utility, make sure that you&#8217;ve checked “Create Config data RPD” when generating the JIC. Then, using the flash API mentioned above, copy the RPD file into the flash from address 0 to make it load when the FPGA powers up, or to a higher address for using the bitstream with a Remote Update core (allowing configuration from higher addresses).</p>
<p>And note the following, which relates to my experience with using the EPCQ16 flash for AS configuring an Cyclone IV E FPGA, and running Quartus Prime Version 15.1.0 Build 185 (YMMV):</p>
<ul>
<li><strong>Bit reversal is mandatory</strong> if epcs_write_buffer() is used for writing to the flash (or any other Nios API, I suppose). That means that for each byte in the RPD file, move bit 7 to bit 0, bit 6 to bit 1 etc. There are small hints of bit reversal spread out in the docs, for  example, in the “Read Bytes Operation” section of the Quad-Serial  Configuration (EPCQ) Devices Datasheet.</li>
<li>All my attempts to generate RBF or RPD files in other ways, including using the command line tool (quartus_cpf) to create an RBF from the SOF or an RPD from a POF failed. That is, I got RBF and RPD files, but they slightly different from the file that eventually worked. In particular, the RBF file obtained with
<pre><del>quartus_cpf -c project.sof project.rbf</del></pre>
<p>was almost identical to the RPD file that worked properly, with a few bytes different in the 0x20-0x4f positions of the files. And that difference probably made the FPGA refuse to configure from it. Go figure.</li>
<li>If you&#8217;re really into generating the flash image with command line tools, generate a COF file (containing the configuration parameters) with the GUI, and use it with something like
<pre>quartus_cpf -c project.cof</pre>
<p>The trick about this COF is that it should generate a proper JIC file, but have the &lt;auto_create_rpd&gt; part set to &#8220;1&#8243;.</li>
</ul>
<p>And finally, just a few sources I found (slightly unrelated):</p>
<ul>
<li><a href="https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/an/an418.pdf" target="_blank">Srunner</a> is a command line utility for programming a EPCS flash. Since<a href="https://www.altera.com/support/support-resources/download/legacy/srunner.html" target="_blank"> source code</a> is given, it can give some insights, as well as its documentation.</li>
<li>The format of POF files is outlined in <a href="http://www.pldtool.com/pdf/fmt_pof.pdf" target="_blank">fmt_pof.pdf</a>.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://billauer.co.il/blog/2017/04/altera-ecpq-active-serial-nios/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>gcc: Solving &#8220;undefined reference&#8221; even when the required library is listed with -l</title>
		<link>http://billauer.co.il/blog/2017/04/gcc-ld-link-debian/</link>
		<comments>http://billauer.co.il/blog/2017/04/gcc-ld-link-debian/#comments</comments>
		<pubDate>Wed, 19 Apr 2017 06:11:51 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://billauer.co.il/blog/?p=5199</guid>
		<description><![CDATA[It worked all so nicely on my Fedora 12 machine, and then on Ubuntu 14.04.1 it failed colossally: $ make gcc -Wall  -O3 -g -lusb-1.0 -c  -o bulkread.o bulkread.c gcc -Wall  -O3 -g -lusb-1.0 -c  -o usberrors.o usberrors.c gcc -Wall  -O3 -g -lusb-1.0 bulkread.o usberrors.o -o bulkread bulkread.o: In function `main': bulkread.c:39: undefined reference to [...]]]></description>
			<content:encoded><![CDATA[<p>It worked all so nicely on my Fedora 12 machine, and then on Ubuntu 14.04.1 it failed colossally:</p>
<pre>$ make
gcc -Wall  -O3 -g -lusb-1.0 -c  -o bulkread.o bulkread.c
gcc -Wall  -O3 -g -lusb-1.0 -c  -o usberrors.o usberrors.c
gcc -Wall  -O3 -g <span style="color: #ff0000;"><strong>-lusb-1.0</strong></span> bulkread.o usberrors.o -o bulkread
bulkread.o: In function `main':
bulkread.c:39: undefined reference to `libusb_init'
bulkread.c:46: undefined reference to `libusb_set_debug'
bulkread.c:48: undefined reference to `libusb_open_device_with_vid_pid'
<span style="color: #999999;"><em>[ ... ]</em></span></pre>
<p>And it went on and on. Note that there was no complaint about not finding the library, and yet it failed to find the symbols.</p>
<p>The problem was the position of the -l flag. It <a href="http://stackoverflow.com/questions/42113237/undefined-reference-when-linking-dynamic-library-in-ubuntu-system" target="_blank">turns out</a> that Ubuntu silently adds an &#8211;as-needed flag to the linker, which effectively means that the -l flag must appear after the object file that needs the symbols, or it will be effectively ignored.</p>
<p>So the correct way is:</p>
<pre>$ make
gcc -Wall  -O3 -g -c  -o bulkread.o bulkread.c
gcc -Wall  -O3 -g -c  -o usberrors.o usberrors.c
gcc -Wall  -O3 -g bulkread.o usberrors.o -o bulkread <span style="color: #ff0000;"><strong>-lusb-1.0</strong></span></pre>
<p>It&#8217;s all about the flag&#8217;s position&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://billauer.co.il/blog/2017/04/gcc-ld-link-debian/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XEmacs / VHDL: Stop that annoying &#8220;assistance&#8221; while typing</title>
		<link>http://billauer.co.il/blog/2017/04/xemacs-vhdl-mode/</link>
		<comments>http://billauer.co.il/blog/2017/04/xemacs-vhdl-mode/#comments</comments>
		<pubDate>Mon, 10 Apr 2017 16:48:55 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[FPGA]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://billauer.co.il/blog/?p=5196</guid>
		<description><![CDATA[Emacs&#8217; (and hence XEmacs&#8217;) VHDL mode has an annoying thing about hopping in and &#8220;help me&#8221; with composing code. Type &#8220;if&#8221; and it tells me I need to add an expression. Thanks. I wouldn&#8217;t have figured it out myself. So here&#8217;s how to disable this annoyance: Add in~/.xemacs/custom.el, to the custom-set-variables clause '(vhdl-electric-mode nil) '(vhdl-stutter-mode [...]]]></description>
			<content:encoded><![CDATA[<p>Emacs&#8217; (and hence XEmacs&#8217;) VHDL mode has an annoying thing about hopping in and &#8220;help me&#8221; with composing code. Type &#8220;if&#8221; and it tells me I need to add an expression. Thanks. I wouldn&#8217;t have figured it out myself.</p>
<p>So here&#8217;s how to disable this annoyance:</p>
<p>Add in~/.xemacs/custom.el, to the custom-set-variables clause</p>
<pre>'(vhdl-electric-mode nil)
'(vhdl-stutter-mode nil)
</pre>
<p>or turn off the respective options inside XEmacs, under VHDL &gt; Options &gt; Mode, and then VHDL &gt; Options &gt; Save Options</p>
<p>And enjoy the bliss of an editor doing what it&#8217;s supposed to do.</p>
]]></content:encoded>
			<wfw:commentRss>http://billauer.co.il/blog/2017/04/xemacs-vhdl-mode/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quartus&#8217; timing analysis on set_input_delay and set_output_delay constraints</title>
		<link>http://billauer.co.il/blog/2017/04/io-timing-quartus-calculation/</link>
		<comments>http://billauer.co.il/blog/2017/04/io-timing-quartus-calculation/#comments</comments>
		<pubDate>Thu, 06 Apr 2017 09:15:26 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[Altera]]></category>
		<category><![CDATA[FPGA]]></category>

		<guid isPermaLink="false">http://billauer.co.il/blog/?p=5188</guid>
		<description><![CDATA[OK, what&#8217;s this? This page is the example part of another post, which explains the meaning of set_input_delay and set_output_delay in SDC timing constraints. TimeQuest (Quartus&#8217; timing analyzer) performs a four-corner check (max/min temperature, max/min voltage) and picks the worst slack. In the examples below, the worst case of these four corners is shown. It&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<h3>OK, what&#8217;s this?</h3>
<p><strong>This page is the example part of <a href="http://billauer.co.il/blog/2017/04/io-timing-constraints-meaning/" target="_blank">another post</a></strong>, which explains the meaning of set_input_delay and set_output_delay in SDC timing constraints.</p>
<p>TimeQuest (Quartus&#8217; timing analyzer) performs a four-corner check (max/min temperature, max/min voltage) and picks the worst slack. In the examples below, the worst case of these four corners is shown. It&#8217;s not exactly clear why a certain delay model becomes the worst case all the times.</p>
<p>As mentioned on the other post, the relevant timing constraints were:</p>
<pre>create_clock -name theclk -period 20 [get_ports test_clk]
set_output_delay -clock theclk -max 8 [get_ports test_out]
set_output_delay -clock theclk -min -3 [get_ports test_out]
set_input_delay -clock theclk -max 4 [get_ports test_in]
set_input_delay -clock theclk -min 2 [get_ports test_in]</pre>
<h3>set_input_delay -max timing analysis (setup)</h3>
<pre>Delay Model:
    Slow 1100mV 0C Model

+------------------------------------------------------------------------------------------------------+
; Summary of Paths                                                                                     ;
+--------+-----------+-----------+--------------+-------------+--------------+------------+------------+
; Slack  ; From Node ; To Node   ; Launch Clock ; Latch Clock ; Relationship ; Clock Skew ; Data Delay ;
+--------+-----------+-----------+--------------+-------------+--------------+------------+------------+
; 12.341 ; test_in   ; test_samp ; theclk       ; theclk      ; 20.000       ; 3.940      ; <span style="color: #ff0000;"><strong>7.499</strong></span>      ;
+--------+-----------+-----------+--------------+-------------+--------------+------------+------------+

Path #1: Setup slack is 12.341
===============================================================================
+--------------------------------+
; Path Summary                   ;
+--------------------+-----------+
; Property           ; Value     ;
+--------------------+-----------+
; From Node          ; test_in   ;
; To Node            ; test_samp ;
; Launch Clock       ; theclk    ;
; Latch Clock        ; theclk    ;
<span style="color: #ff0000;"><strong>; Data Arrival Time  ; 11.499    ;
; Data Required Time ; 23.840    ;
; Slack              ; 12.341    ;
</strong></span>+--------------------+-----------+

+---------------------------------------------------------------------------------------+
; Statistics                                                                            ;
+---------------------------+--------+-------+-------------+------------+-------+-------+
; Property                  ; Value  ; Count ; Total Delay ; % of Total ; Min   ; Max   ;
+---------------------------+--------+-------+-------------+------------+-------+-------+
; Setup Relationship        ; 20.000 ;       ;             ;            ;       ;       ;
; Clock Skew                ; 3.940  ;       ;             ;            ;       ;       ;
; Data Delay                ; 7.499  ;       ;             ;            ;       ;       ;
; Number of Logic Levels    ;        ; 1     ;             ;            ;       ;       ;
; Physical Delays           ;        ;       ;             ;            ;       ;       ;
;  Arrival Path             ;        ;       ;             ;            ;       ;       ;
;   Clock                   ;        ;       ;             ;            ;       ;       ;
;    Clock Network (Lumped) ;        ; 1     ; 0.000       ;            ; 0.000 ; 0.000 ;
;   Data                    ;        ;       ;             ;            ;       ;       ;
;    IC                     ;        ; 2     ; 2.447       ; 33         ; 0.000 ; 2.447 ;
;    Cell                   ;        ; 2     ; 5.052       ; 67         ; 0.652 ; 4.400 ;
;  Required Path            ;        ;       ;             ;            ;       ;       ;
;   Clock                   ;        ;       ;             ;            ;       ;       ;
;    Clock Network (Lumped) ;        ; 1     ; 3.940       ; 100        ; 3.940 ; 3.940 ;
+---------------------------+--------+-------+-------------+------------+-------+-------+
Note: Negative delays are omitted from totals when calculating percentages

+-----------------------------------------------------------------------------------+
; Data Arrival Path                                                                 ;
+----------+---------+----+------+--------+-------------------+---------------------+
; Total    ; Incr    ; RF ; Type ; Fanout ; Location          ; Element             ;
+----------+---------+----+------+--------+-------------------+---------------------+
; 0.000    ; 0.000   ;    ;      ;        ;                   ; launch edge time    ;
; 0.000    ; 0.000   ;    ;      ;        ;                   ; clock path          ;
;   0.000  ;   0.000 ; R  ;      ;        ;                   ; clock network delay ;
<span style="color: #ff0000;"><strong>; 4.000    ; 4.000   ; F  ; iExt ; 1      ; PIN_AP17          ; test_in             ;
</strong></span>; 11.499   ; 7.499   ;    ;      ;        ;                   ; data path           ;
;   4.000  ;   0.000 ; FF ; IC   ; 1      ; IOIBUF_X48_Y0_N58 ; test_in~input|i     ;
;   8.400  ;   4.400 ; FF ; CELL ; 1      ; IOIBUF_X48_Y0_N58 ; test_in~input|o     ;
;   10.847 ;   2.447 ; FF ; IC   ; 1      ; FF_X48_Y2_N40     ; test_samp|asdata    ;
;   11.499 ;   0.652 ; FF ; CELL ; 1      ; FF_X48_Y2_N40     ; test_samp           ;
+----------+---------+----+------+--------+-------------------+---------------------+

+-------------------------------------------------------------------------------+
; Data Required Path                                                            ;
+----------+---------+----+------+--------+---------------+---------------------+
; Total    ; Incr    ; RF ; Type ; Fanout ; Location      ; Element             ;
+----------+---------+----+------+--------+---------------+---------------------+
; 20.000   ; 20.000  ;    ;      ;        ;               ; latch edge time     ;
; 23.940   ; 3.940   ;    ;      ;        ;               ; clock path          ;
;   23.940 ;   3.940 ; R  ;      ;        ;               ; clock network delay ;
; 23.840   ; -0.100  ;    ;      ;        ;               ; clock uncertainty   ;
; 23.840   ; 0.000   ;    ; uTsu ; 1      ; FF_X48_Y2_N40 ; test_samp           ;
+----------+---------+----+------+--------+---------------+---------------------+</pre>
<p>This analysis starts in &#8220;Data Arrival Path&#8221; with setting the input port (test_in) at 4 ns as specified in the <strong>max input delay</strong> constraint, and continues that data path. Together with  the FPGA&#8217;s own data path delay (7.499  ns), the total data path delay  stands at 11.499 ns.</p>
<p>The clock path is the calculated in &#8220;Data Required Path&#8221;,  starting from the <strong>following</strong> clock at 20 ns. The clock travels from the input pin to the flip-flop  (with no clock network delay compensation, since no PLL is involved),  taking into account the calculated jitter.  All in all, the clock path  ends at 23.840 ns, which is 12.341 ns after the data arrived to the  flip-flop, which is this constraint&#8217;s slack.</p>
<p>It&#8217;s simple to see from this analysis that the max input delay is the  clock-to-output ( + board delay), as it&#8217;s the starting time of the data path.</p>
<h3>set_input_delay -min timing analysis (hold)</h3>
<pre>Delay Model:
    Slow 1100mV 85C Model

+-----------------------------------------------------------------------------------------------------+
; Summary of Paths                                                                                    ;
+-------+-----------+-----------+--------------+-------------+--------------+------------+------------+
; Slack ; From Node ; To Node   ; Launch Clock ; Latch Clock ; Relationship ; Clock Skew ; Data Delay ;
+-------+-----------+-----------+--------------+-------------+--------------+------------+------------+
; 0.770 ; test_in   ; test_samp ; theclk       ; theclk      ; 0.000        ; 4.287      ; <span style="color: #ff0000;"><strong>3.057</strong></span>      ;
+-------+-----------+-----------+--------------+-------------+--------------+------------+------------+

Path #1: Hold slack is 0.770
===============================================================================
+--------------------------------+
; Path Summary                   ;
+--------------------+-----------+
; Property           ; Value     ;
+--------------------+-----------+
; From Node          ; test_in   ;
; To Node            ; test_samp ;
; Launch Clock       ; theclk    ;
; Latch Clock        ; theclk    ;
<span style="color: #ff0000;"><strong>; Data Arrival Time  ; 5.057     ;
; Data Required Time ; 4.287     ;
; Slack              ; 0.770     ;
</strong></span>+--------------------+-----------+

+--------------------------------------------------------------------------------------+
; Statistics                                                                           ;
+---------------------------+-------+-------+-------------+------------+-------+-------+
; Property                  ; Value ; Count ; Total Delay ; % of Total ; Min   ; Max   ;
+---------------------------+-------+-------+-------------+------------+-------+-------+
; Hold Relationship         ; 0.000 ;       ;             ;            ;       ;       ;
; Clock Skew                ; 4.287 ;       ;             ;            ;       ;       ;
; Data Delay                ; 3.057 ;       ;             ;            ;       ;       ;
; Number of Logic Levels    ;       ; 1     ;             ;            ;       ;       ;
; Physical Delays           ;       ;       ;             ;            ;       ;       ;
;  Arrival Path             ;       ;       ;             ;            ;       ;       ;
;   Clock                   ;       ;       ;             ;            ;       ;       ;
;    Clock Network (Lumped) ;       ; 1     ; 0.000       ;            ; 0.000 ; 0.000 ;
;   Data                    ;       ;       ;             ;            ;       ;       ;
;    IC                     ;       ; 2     ; 2.028       ; 66         ; 0.000 ; 2.028 ;
;    Cell                   ;       ; 2     ; 1.029       ; 34         ; 0.290 ; 0.739 ;
;  Required Path            ;       ;       ;             ;            ;       ;       ;
;   Clock                   ;       ;       ;             ;            ;       ;       ;
;    Clock Network (Lumped) ;       ; 1     ; 4.287       ; 100        ; 4.287 ; 4.287 ;
+---------------------------+-------+-------+-------------+------------+-------+-------+
Note: Negative delays are omitted from totals when calculating percentages

+----------------------------------------------------------------------------------+
; Data Arrival Path                                                                ;
+---------+---------+----+------+--------+-------------------+---------------------+
; Total   ; Incr    ; RF ; Type ; Fanout ; Location          ; Element             ;
+---------+---------+----+------+--------+-------------------+---------------------+
; 0.000   ; 0.000   ;    ;      ;        ;                   ; launch edge time    ;
; 0.000   ; 0.000   ;    ;      ;        ;                   ; clock path          ;
;   0.000 ;   0.000 ; R  ;      ;        ;                   ; clock network delay ;
<span style="color: #ff0000;"><strong>; 2.000   ; 2.000   ; R  ; iExt ; 1      ; PIN_AP17          ; test_in             ;
</strong></span>; 5.057   ; 3.057   ;    ;      ;        ;                   ; data path           ;
;   2.000 ;   0.000 ; RR ; IC   ; 1      ; IOIBUF_X48_Y0_N58 ; test_in~input|i     ;
;   2.739 ;   0.739 ; RR ; CELL ; 1      ; IOIBUF_X48_Y0_N58 ; test_in~input|o     ;
;   4.767 ;   2.028 ; RR ; IC   ; 1      ; FF_X48_Y2_N40     ; test_samp|asdata    ;
;   5.057 ;   0.290 ; RR ; CELL ; 1      ; FF_X48_Y2_N40     ; test_samp           ;
+---------+---------+----+------+--------+-------------------+---------------------+

+------------------------------------------------------------------------------+
; Data Required Path                                                           ;
+---------+---------+----+------+--------+---------------+---------------------+
; Total   ; Incr    ; RF ; Type ; Fanout ; Location      ; Element             ;
+---------+---------+----+------+--------+---------------+---------------------+
; 0.000   ; 0.000   ;    ;      ;        ;               ; latch edge time     ;
; 4.287   ; 4.287   ;    ;      ;        ;               ; clock path          ;
;   4.287 ;   4.287 ; R  ;      ;        ;               ; clock network delay ;
; 4.287   ; 0.000   ;    ;      ;        ;               ; clock uncertainty   ;
; 4.287   ; 0.000   ;    ; uTh  ; 1      ; FF_X48_Y2_N40 ; test_samp           ;
+---------+---------+----+------+--------+---------------+---------------------+</pre>
<p>This analysis starts in “Data Arrival Path” with setting the input port (test_in) at 2 ns as specified in the <strong>min input delay</strong> constraint, and continues that data path. Together  with the  FPGA&#8217;s own data path delay (3.057 ns), the total data path  delay stands  at 5.057 ns.</p>
<p>The clock path is the calculated in “Data Required Path”, starting from the <strong>same  clock edge at 0 ns</strong>.  After all, this is a hold calculation, so the question is whether the  mat wasn&#8217;t swept under the feet of the sampling flip-flop before it  managed to sample it.</p>
<p>The clock travels from the input pin to the flip-flop  (with no clock  network delay compensation, since no PLL is involved),  taking into  account the calculated jitter.  All in all, the clock path  ends at 4.287 ns, which is 0.770 ns earlier than the data switching, which is also the slack.</p>
<p>It&#8217;s simple to see from this analysis that the min input delay is the   minimal clock-to-output, as it’s the starting time of the data path.</p>
<h3>set_output_delay -max timing analysis (setup)</h3>
<pre>Delay Model:
    Slow 1100mV 85C Model

+--------------------------------------------------------------------------------------------------------+
; Summary of Paths                                                                                       ;
+-------+---------------+----------+--------------+-------------+--------------+------------+------------+
; Slack ; From Node     ; To Node  ; Launch Clock ; Latch Clock ; Relationship ; Clock Skew ; Data Delay ;
+-------+---------------+----------+--------------+-------------+--------------+------------+------------+
; 2.651 ; test_out~reg0 ; test_out ; theclk       ; theclk      ; 20.000       ; -5.320     ; <span style="color: #ff0000;"><strong>3.929</strong></span>      ;
+-------+---------------+----------+--------------+-------------+--------------+------------+------------+

Path #1: Setup slack is 2.651
===============================================================================
+------------------------------------+
; Path Summary                       ;
+--------------------+---------------+
; Property           ; Value         ;
+--------------------+---------------+
; From Node          ; test_out~reg0 ;
; To Node            ; test_out      ;
; Launch Clock       ; theclk        ;
; Latch Clock        ; theclk        ;
<span style="color: #ff0000;"><strong>; Data Arrival Time  ; 9.249         ;
; Data Required Time ; 11.900        ;
; Slack              ; 2.651         ;
</strong></span>+--------------------+---------------+

+---------------------------------------------------------------------------------------+
; Statistics                                                                            ;
+---------------------------+--------+-------+-------------+------------+-------+-------+
; Property                  ; Value  ; Count ; Total Delay ; % of Total ; Min   ; Max   ;
+---------------------------+--------+-------+-------------+------------+-------+-------+
; Setup Relationship        ; 20.000 ;       ;             ;            ;       ;       ;
; Clock Skew                ; -5.320 ;       ;             ;            ;       ;       ;
; Data Delay                ; 3.929  ;       ;             ;            ;       ;       ;
; Number of Logic Levels    ;        ; 0     ;             ;            ;       ;       ;
; Physical Delays           ;        ;       ;             ;            ;       ;       ;
;  Arrival Path             ;        ;       ;             ;            ;       ;       ;
;   Clock                   ;        ;       ;             ;            ;       ;       ;
;    Clock Network (Lumped) ;        ; 1     ; 5.320       ; 100        ; 5.320 ; 5.320 ;
;   Data                    ;        ;       ;             ;            ;       ;       ;
;    IC                     ;        ; 1     ; 0.000       ; 0          ; 0.000 ; 0.000 ;
;    Cell                   ;        ; 3     ; 3.929       ; 100        ; 0.000 ; 2.150 ;
;    uTco                   ;        ; 1     ; 0.000       ; 0          ; 0.000 ; 0.000 ;
;  Required Path            ;        ;       ;             ;            ;       ;       ;
;   Clock                   ;        ;       ;             ;            ;       ;       ;
;    Clock Network (Lumped) ;        ; 1     ; 0.000       ;            ; 0.000 ; 0.000 ;
+---------------------------+--------+-------+-------------+------------+-------+-------+
Note: Negative delays are omitted from totals when calculating percentages

+---------------------------------------------------------------------------------------+
; Data Arrival Path                                                                     ;
+---------+---------+----+------+--------+------------------------+---------------------+
; Total   ; Incr    ; RF ; Type ; Fanout ; Location               ; Element             ;
+---------+---------+----+------+--------+------------------------+---------------------+
; 0.000   ; 0.000   ;    ;      ;        ;                        ; launch edge time    ;
; 5.320   ; 5.320   ;    ;      ;        ;                        ; clock path          ;
;   5.320 ;   5.320 ; R  ;      ;        ;                        ; clock network delay ;
; 9.249   ; 3.929   ;    ;      ;        ;                        ; data path           ;
;   5.320 ;   0.000 ;    ; uTco ; 1      ; DDIOOUTCELL_X48_Y0_N50 ; test_out~reg0       ;
;   7.099 ;   1.779 ; FF ; CELL ; 1      ; DDIOOUTCELL_X48_Y0_N50 ; test_out~reg0|q     ;
;   7.099 ;   0.000 ; FF ; IC   ; 1      ; IOOBUF_X48_Y0_N42      ; test_out~output|i   ;
;   9.249 ;   2.150 ; FF ; CELL ; 1      ; IOOBUF_X48_Y0_N42      ; test_out~output|o   ;
;   9.249 ;   0.000 ; FF ; CELL ; 0      ; PIN_AN17               ; test_out            ;
+---------+---------+----+------+--------+------------------------+---------------------+

+--------------------------------------------------------------------------+
; Data Required Path                                                       ;
+----------+---------+----+------+--------+----------+---------------------+
; Total    ; Incr    ; RF ; Type ; Fanout ; Location ; Element             ;
+----------+---------+----+------+--------+----------+---------------------+
; 20.000   ; 20.000  ;    ;      ;        ;          ; latch edge time     ;
; 20.000   ; 0.000   ;    ;      ;        ;          ; clock path          ;
;   20.000 ;   0.000 ; R  ;      ;        ;          ; clock network delay ;
; 19.900   ; -0.100  ;    ;      ;        ;          ; clock uncertainty   ;
<span style="color: #ff0000;"><strong>; 11.900   ; -8.000  ; F  ; oExt ; 0      ; PIN_AN17 ; test_out            ;
</strong></span>+----------+---------+----+------+--------+----------+---------------------+</pre>
<p>Since the purpose of this analysis is to measure the output delay, it  starts off in &#8220;Data Arrival Path&#8221; with the clock edge, adds the clock network delay to the flip-flop, and  then goes along the data path until the physical output is stable, calculated at 9.249 ns.</p>
<p>This is compared with the time of the <strong>following</strong> clock at 20  ns, minus the output delay. Minus the possible jitter (0.1 ns in the  case above). Data arrived at 9.249 ns, the moment that counts is at 11.9 ns, so there&#8217;s a 2.651 ns slack.</p>
<p>This demonstrates why set_output_delay -max is the setup time of the  receiver: The output delay is reduced from the following clock&#8217;s time  position, and that&#8217;s the goal to meet. That&#8217;s exactly the definition of  setup time: How long before the following clock the data must be stable.</p>
<h3>set_output_delay -min timing analysis (hold)</h3>
<pre>Delay Model:
    Fast 1100mV 0C Model

+--------------------------------------------------------------------------------------------------------+
; Summary of Paths                                                                                       ;
+-------+---------------+----------+--------------+-------------+--------------+------------+------------+
; Slack ; From Node     ; To Node  ; Launch Clock ; Latch Clock ; Relationship ; Clock Skew ; Data Delay ;
+-------+---------------+----------+--------------+-------------+--------------+------------+------------+
; 1.275 ; test_out~reg0 ; test_out ; theclk       ; theclk      ; 0.000        ; -2.255     ; <span style="color: #ff0000;"><strong>2.020</strong></span>      ;
+-------+---------------+----------+--------------+-------------+--------------+------------+------------+

Path #1: Hold slack is 1.275
===============================================================================
+------------------------------------+
; Path Summary                       ;
+--------------------+---------------+
; Property           ; Value         ;
+--------------------+---------------+
; From Node          ; test_out~reg0 ;
; To Node            ; test_out      ;
; Launch Clock       ; theclk        ;
; Latch Clock        ; theclk        ;
<span style="color: #ff0000;"><strong>; Data Arrival Time  ; 4.275         ;
; Data Required Time ; 3.000         ;
; Slack              ; 1.275         ;
</strong></span>+--------------------+---------------+

+---------------------------------------------------------------------------------------+
; Statistics                                                                            ;
+---------------------------+--------+-------+-------------+------------+-------+-------+
; Property                  ; Value  ; Count ; Total Delay ; % of Total ; Min   ; Max   ;
+---------------------------+--------+-------+-------------+------------+-------+-------+
; Hold Relationship         ; 0.000  ;       ;             ;            ;       ;       ;
; Clock Skew                ; -2.255 ;       ;             ;            ;       ;       ;
; Data Delay                ; 2.020  ;       ;             ;            ;       ;       ;
; Number of Logic Levels    ;        ; 0     ;             ;            ;       ;       ;
; Physical Delays           ;        ;       ;             ;            ;       ;       ;
;  Arrival Path             ;        ;       ;             ;            ;       ;       ;
;   Clock                   ;        ;       ;             ;            ;       ;       ;
;    Clock Network (Lumped) ;        ; 1     ; 2.255       ; 100        ; 2.255 ; 2.255 ;
;   Data                    ;        ;       ;             ;            ;       ;       ;
;    IC                     ;        ; 1     ; 0.000       ; 0          ; 0.000 ; 0.000 ;
;    Cell                   ;        ; 3     ; 2.020       ; 100        ; 0.000 ; 1.296 ;
;    uTco                   ;        ; 1     ; 0.000       ; 0          ; 0.000 ; 0.000 ;
;  Required Path            ;        ;       ;             ;            ;       ;       ;
;   Clock                   ;        ;       ;             ;            ;       ;       ;
;    Clock Network (Lumped) ;        ; 1     ; 0.000       ;            ; 0.000 ; 0.000 ;
+---------------------------+--------+-------+-------------+------------+-------+-------+
Note: Negative delays are omitted from totals when calculating percentages

+---------------------------------------------------------------------------------------+
; Data Arrival Path                                                                     ;
+---------+---------+----+------+--------+------------------------+---------------------+
; Total   ; Incr    ; RF ; Type ; Fanout ; Location               ; Element             ;
+---------+---------+----+------+--------+------------------------+---------------------+
; 0.000   ; 0.000   ;    ;      ;        ;                        ; launch edge time    ;
; 2.255   ; 2.255   ;    ;      ;        ;                        ; clock path          ;
;   2.255 ;   2.255 ; R  ;      ;        ;                        ; clock network delay ;
; 4.275   ; 2.020   ;    ;      ;        ;                        ; data path           ;
;   2.255 ;   0.000 ;    ; uTco ; 1      ; DDIOOUTCELL_X48_Y0_N50 ; test_out~reg0       ;
;   2.979 ;   0.724 ; RR ; CELL ; 1      ; DDIOOUTCELL_X48_Y0_N50 ; test_out~reg0|q     ;
;   2.979 ;   0.000 ; RR ; IC   ; 1      ; IOOBUF_X48_Y0_N42      ; test_out~output|i   ;
;   4.275 ;   1.296 ; RR ; CELL ; 1      ; IOOBUF_X48_Y0_N42      ; test_out~output|o   ;
;   4.275 ;   0.000 ; RR ; CELL ; 0      ; PIN_AN17               ; test_out            ;
+---------+---------+----+------+--------+------------------------+---------------------+

+-------------------------------------------------------------------------+
; Data Required Path                                                      ;
+---------+---------+----+------+--------+----------+---------------------+
; Total   ; Incr    ; RF ; Type ; Fanout ; Location ; Element             ;
+---------+---------+----+------+--------+----------+---------------------+
; 0.000   ; 0.000   ;    ;      ;        ;          ; latch edge time     ;
; 0.000   ; 0.000   ;    ;      ;        ;          ; clock path          ;
;   0.000 ;   0.000 ; R  ;      ;        ;          ; clock network delay ;
; 0.000   ; 0.000   ;    ;      ;        ;          ; clock uncertainty   ;
<span style="color: #ff0000;"><strong>; 3.000   ; 3.000   ; R  ; oExt ; 0      ; PIN_AN17 ; test_out            ;
</strong></span>+---------+---------+----+------+--------+----------+---------------------+</pre>
<p>This analysis is similar to the max output delay, only it&#8217;s calculated against  the same clock edge (and not the following one).</p>
<p>As before, the data path continues the clock path until the physical  output is stable, calculated at 4.275 ns.</p>
<p>This is compared with the time of the <strong>same</strong> clock at 0  ns,  minus the output delay. Recall that the min output delay was negative (-3 ns), which is  why it appears as a positive number in the calculation.</p>
<p>Conclusion: Data was stable until 4.275 ns, and needs to be stable until 3 ns.  That&#8217;s fine, with a 1.275 ns slack.</p>
<p>This demonstrates why set_output_delay -min is minus the hold time of  the  receiver: The given output delay with reversed sign  is used as the time which the data path delay <strong>must exceed</strong>. In other words, the data must be stable for that long after the clock. This is the definition of hold time.</p>
]]></content:encoded>
			<wfw:commentRss>http://billauer.co.il/blog/2017/04/io-timing-quartus-calculation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
