<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Dmitry Dvoinikov</title>
    <description>The latest articles on Forem by Dmitry Dvoinikov (@targeted).</description>
    <link>https://forem.com/targeted</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F171706%2Ff3daaea1-1202-4476-951c-87abeff89476.png</url>
      <title>Forem: Dmitry Dvoinikov</title>
      <link>https://forem.com/targeted</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/targeted"/>
    <language>en</language>
    <item>
      <title>Alien biohazard approach to security</title>
      <dc:creator>Dmitry Dvoinikov</dc:creator>
      <pubDate>Thu, 18 Jul 2024 10:06:33 +0000</pubDate>
      <link>https://forem.com/targeted/alien-biohazard-approach-to-security-3bmj</link>
      <guid>https://forem.com/targeted/alien-biohazard-approach-to-security-3bmj</guid>
      <description>&lt;p&gt;Generally speaking, security is all about threats and their mitigation. So the textbook approach is to sit down, enumerate the possible threats, write them all down and eliminate one by one.&lt;/p&gt;

&lt;p&gt;You don't need me to tell you the ways it goes wrong.&lt;/p&gt;

&lt;p&gt;One problem is this process is wrapped in bureaucracy, is driven by numbers and often reduced to boilerplate. Of course there must be strong passwords. Of course there must be permissions. Of course you should use SSL for transport. Of course you should not open e-mails.&lt;/p&gt;

&lt;p&gt;By the way, here is a convenient AI-automated solution that will print you an industry standard 120 page security plan. Shareholders happy, auditors happy, good job, well done. There is very little incentive to think outside the box and stay alert, after the plan has been approved and everybody's happy.&lt;/p&gt;

&lt;p&gt;But as you know, reality does not work like that.&lt;/p&gt;

&lt;p&gt;Instead, the way I think about security is as if I was part of a task force landing on an alien planet. It is dangerous. It is deadly. It is full of viruses, none of which were seen before. Your equipment may be inadequate and will fail at the worst possible moment.&lt;/p&gt;

&lt;p&gt;So what do you do all alone and vulnerable in a foreign environment which is hellbent on killing you ?&lt;/p&gt;

&lt;p&gt;First, you set the rules and never break them. There must be a handful of basic principles, from which you don't deviate. No exceptions.&lt;/p&gt;

&lt;p&gt;Second, you use everything you have. The measures that you take must back each other up, and be applied meticulously and in order. No shortcuts, no workarounds.&lt;/p&gt;

&lt;p&gt;Third, you keep tightening the bolts. Look at everything as if it was about to break, the question only being when and how. Fix everything immediately, don't rest assured.&lt;/p&gt;

&lt;p&gt;Finally, and most importantly, you plan not for safety, but for containment. The best pattern here is the airlock. One way in, one way out, designed to be locked shut and incinerated in a second.&lt;/p&gt;

&lt;p&gt;On to the next planet.&lt;/p&gt;

</description>
      <category>security</category>
      <category>cybersecurity</category>
      <category>design</category>
    </item>
    <item>
      <title>Honor MagicBook Pro 2020 laptop, a tale of great hardware and terrible support</title>
      <dc:creator>Dmitry Dvoinikov</dc:creator>
      <pubDate>Thu, 29 Apr 2021 17:29:41 +0000</pubDate>
      <link>https://forem.com/targeted/honor-magicbook-pro-2020-laptop-a-tale-of-great-hardware-and-terrible-support-4dig</link>
      <guid>https://forem.com/targeted/honor-magicbook-pro-2020-laptop-a-tale-of-great-hardware-and-terrible-support-4dig</guid>
      <description>&lt;p&gt;This is a story of buying a Honor MagicBook Pro 2020 laptop in Germany.&lt;/p&gt;

&lt;p&gt;As you may know, German keyboard layout is quite awkward. Not only because of the swapped Y and Z, or extra ümläütß, but most of all because the special characters are all mixed up. Makes typing a torture. And it is a primary layout, not secondary one, like Russian, where you could have QWERTY and ЙЦУКЕН sharing the same keys.&lt;/p&gt;

&lt;p&gt;Also, good luck buying a laptop with an English keyboard in Germany. You just can't. They will gladly sell you a German keyboard, but if you want QWERTY, your only choice is to move to UK. Apple takes custom orders, but shall we say I'm not a big fan of Apple. Not to mention I was going to buy a workstation class notebook out of my own pocket.&lt;/p&gt;

&lt;p&gt;Finally I decided to pick one and just see it through. Enter the &lt;a href="https://www.hihonor.com/global/products/laptop/honor-magicbook-pro/" rel="noopener noreferrer"&gt;Honor Magic Book Pro 2020&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvswhxo0t9xlor0lpb7jp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvswhxo0t9xlor0lpb7jp.png" alt="Honor MagicBook Pro 2020" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wonderful laptop, extremely powerful, well made and not expensive. Except for the useless webcam buried in the keyboard, everything is else is exactly what the doctor ordered for a developer's workstation. But the keyboard, the impossible German keyboard.&lt;/p&gt;




&lt;p&gt;And so my first letter to the German Honor support goes "Can haz QWERTY ?" Got no response at all. &lt;/p&gt;

&lt;p&gt;Tried UK support with "Can haz QWERTY delivered to Germany ?" Got an immediate "No, go ask Germany"&lt;/p&gt;

&lt;p&gt;Second attempt with German support. "Can haz QWERTY plz ?" This time the response was fantastic: "No it is not possible, but buy one from ebay and give me a 5 stars feedback for this answer." Signed "Karl". Let's call him "Karl from Honor".&lt;/p&gt;

&lt;p&gt;Well, I got to ebay, and found what I needed from &lt;a href="http://www.ebay.de/usr/helloworld2003" rel="noopener noreferrer"&gt;helloworld2003&lt;/a&gt;. This guy turned out more helpful than all the official support. A couple of weeks later I got the laptop in my hands and let me just tell you, it's as impressive as I hoped.&lt;/p&gt;

&lt;p&gt;And I was ready to see Chinese Windows 10 too. Reinstalled the English one clean, went without a hitch, except for the fingerprint scanner was not recognized. &lt;/p&gt;

&lt;p&gt;Ready for the second round of support ?&lt;/p&gt;

&lt;p&gt;Here goes: "I did as official support suggested, can haz driver plz ?" Response: "All support for Honor products manufactured before 2021 is done by Huawei, go ask them."&lt;/p&gt;

&lt;p&gt;Now to Huawei: "Here is the entire story, can haz driver plz ?". Guess who replied from Huawei ? Karl from Honor ! Here is the answer: "We don't have drivers here. Besides, we are German, and you have a Chinese product, go to where you purchased it."&lt;/p&gt;

&lt;p&gt;It is almost like those businesses don't need customers.&lt;/p&gt;

&lt;p&gt;In the end, I wrote to the ebay's seller and asked for a driver. He replied in a few minutes with a direct download URL.&lt;/p&gt;




&lt;p&gt;And the laptop itself is excellent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The latest 6-core Ryzen 5 works on par with 8-core i9-9880H and beats my 16-core dual Xeon under-the-table workstation. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No 4K resolution, just a faithful FullHD on a reasonably bright matte 16". Also, no touch screen.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No numpad, allowing for the keys to be large, the touchpad to remain the middle, and the entire thing to stay symmetric. The keyboard and the touchpad feel nice.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can connect two external displays, one via HDMI and one via USB-C. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Thin and light, almost funny light for a "serious" machine. Quiet and effectively cooled.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Looks really good. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the down side:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;To put a webcam underneath the screen is short of sabotage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;F12 is the same key as Ins. You either have F-keys without Ins, or Ins with all kinds of multimedia keys.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, highly recommended !&lt;/p&gt;

</description>
      <category>hardware</category>
      <category>honor</category>
      <category>laptop</category>
      <category>review</category>
    </item>
    <item>
      <title>First things security</title>
      <dc:creator>Dmitry Dvoinikov</dc:creator>
      <pubDate>Thu, 12 Nov 2020 09:43:44 +0000</pubDate>
      <link>https://forem.com/targeted/first-things-security-hl0</link>
      <guid>https://forem.com/targeted/first-things-security-hl0</guid>
      <description>&lt;p&gt;Security is a state of mind, not a state of things. &lt;/p&gt;

&lt;p&gt;Security of things cannot be achieved. Any system that is complex enough to be secured, is already broken. This is the same kind of broad sentiment as "we'll all die eventually", but it is true. Therefore, you should always start with the premise that your security is broken - then what ?&lt;/p&gt;

&lt;p&gt;At this moment you should think about alternative plans and insurance. In a sense, insurance is the security decision that covers risks that cannot otherwise be covered, such as death.&lt;/p&gt;

&lt;p&gt;From a technical perspective, that all security is broken, leads to two conclusions. First, you must know when to stop being paranoid and give up some of the steps that are hopeless anyway. Second, you should make your security partitioned / layered.&lt;/p&gt;

&lt;p&gt;Partitioning a complex system into components / modules / what have you, is the ultimate analysis principle. It makes things observable, easier to reason about, modify and replace, and, in case of security, they back each other up. When you have a row of ten doors, the attacker has to break ten locks. &lt;/p&gt;

&lt;p&gt;On the other hand, when you partition a system, any system, it only creates an illusion that complexity disappears. Complexity, like energy, never disappears, it only transforms from one state to another. Here, the complexity goes into the interconnections. It is good when you have ten doors one after another, but in reality the parts communicate with each other in a twisted and unpredictable way. And then, another, opposite, security maxim says that the attacker must break just one door, whereas the defender must protect them all. Therefore, the more parts, the more vulnerable the system is. Catch-22.&lt;/p&gt;

&lt;p&gt;Good luck.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Learning FPGA programming, key points for a software developer (part 3, code patterns and inferred behavior)</title>
      <dc:creator>Dmitry Dvoinikov</dc:creator>
      <pubDate>Mon, 03 Aug 2020 08:50:35 +0000</pubDate>
      <link>https://forem.com/targeted/learning-fpga-programming-key-points-for-a-software-developer-part-3-code-patterns-and-inferred-behavior-1j28</link>
      <guid>https://forem.com/targeted/learning-fpga-programming-key-points-for-a-software-developer-part-3-code-patterns-and-inferred-behavior-1j28</guid>
      <description>&lt;p&gt;The previous parts of this article discussed &lt;a href="https://dev.to/targeted/learning-fpga-programming-key-points-for-a-software-developer-18bf"&gt;the time&lt;/a&gt; and &lt;a href="https://dev.to/targeted/learning-fpga-programming-key-points-for-a-software-developer-part-2-registered-logic-j3k"&gt;registered logic&lt;/a&gt;. This part is specifically about &lt;em&gt;writing VHDL&lt;/em&gt;. It opens with general discussion and then presents code samples and analysis.&lt;/p&gt;

&lt;p&gt;VHDL is a declarative language, in which you declare an intent, and let the compiler find the way of implementing it. In a good declarative language it must be easy to express the intent, and the intent must be clear from the code.&lt;/p&gt;

&lt;p&gt;You know what other common language is declarative ? SQL. VHDL and SQL are absolutely unrelated of course, but for an opening illustration SQL could be useful.&lt;/p&gt;

&lt;p&gt;So, in SQL you write queries that manipulate data. Consider the following simplest SQL query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The intent here is to find matching records from relation t and return a set of rows with just x in them. But it would be a mistake to assume that the engine would go through table t, check every record for equality of y and extract x from each. Why ?&lt;/p&gt;

&lt;p&gt;Because nothing even indicates that t is a table and either x or y are fields. t could be a view, and x and y could be calculated expressions, even constants. In the latter case no data access would be required at all. But even if, we have no idea how it is going to be accessed. SQL optimizer might decide to read an index, rather than the table, and then depending on its coverage, a lookup to the table may or may not be required. Also about indexes, nothing suggests that a suitable index exists, heck, that the engine supports indexes in the first place.&lt;/p&gt;

&lt;p&gt;Therefore, to write an efficient SQL query you must take a lot vendor-specific things into account. You may want to read query plans, rearrange the query and even resort to optimizer hints. The query could run either way, but could turn out impractically slow.&lt;/p&gt;

&lt;p&gt;Same is true about VHDL.&lt;/p&gt;

&lt;p&gt;But VHDL is poorly suited for the job. That it looks like a regular imperative language with conditions, loops, functions and even class-like protected structures, suitable for general programming, is extremely misleading. It doesn't follow a theoretical model the way SQL does, nor does it have first class representation for the objects it actually manipulates.&lt;/p&gt;

&lt;p&gt;You should not read nor write VHDL as you would Ada (or Pascal). Instead, you should look at VHDL program the same way the compiler does. And when I say "compiler", I mean the entire chain of tools, or any one in particular.&lt;/p&gt;

&lt;p&gt;What's the purpose of the compiler ? To turn your code into a binary configuration file &lt;em&gt;for a particular FPGA device&lt;/em&gt;. And every device is different, vendors compete by embedding various reusable blocks. Memory blocks, arithmetic units, all kinds of controllers and even entire CPU's make their way to an FPGA chip. Then where one compiler could use a ready block, another will have to implement it from smaller bricks.&lt;/p&gt;

&lt;p&gt;The smallest bricks in FPGA are LUT's (programmable wires) and registers. These are effectively the two kinds of objects we have in a VHDL program. Except for vendor-specific attributes (a-la SQL hints) we never mention anything else. How would a compiler know when to reuse a bigger block, when all it sees is wires and registers ? Besides, even with wires and registers, the best way to arrange them depends on the situation, but how would a compiler even know what the intent was ?&lt;/p&gt;

&lt;p&gt;It would help, if the compiler knew what we &lt;em&gt;meant&lt;/em&gt; from what we &lt;em&gt;wrote&lt;/em&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The compiler tries to guess the meaning by looking for certain patterns in the code. Once a pattern is detected, an expected behavior is inferred and a known solution is applied, hoping that it is correct and efficient. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As with SQL, it may or may not be, and it is inevitable that we have to read the compilation reports and make sure there is no blunder.&lt;/p&gt;

&lt;p&gt;Let's have some examples.&lt;/p&gt;

&lt;p&gt;1 . The simplest pattern is this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vhdl"&gt;&lt;code&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is clearly a multiplication, and an embedded multiplier could be used, or a specific algorithm, depending on how large a and b are.&lt;/p&gt;

&lt;p&gt;2 . This here&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vhdl"&gt;&lt;code&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;std_logic_vector&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;others&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="sc"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;infers a zero comparator. Notice that it is different from a general comparator&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vhdl"&gt;&lt;code&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;std_logic_vector&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;v1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;v2&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and that they produce quite different configurations.&lt;/p&gt;

&lt;p&gt;3 . Patterns could span multiple lines, and as such are more like wildcard fragments in the parsing tree. This here&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vhdl"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cnt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="n"&gt;cnt&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;cnt&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is a counter pattern. Again, notice how counting up produces a very different configuration&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vhdl"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cnt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="n"&gt;cnt&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;cnt&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and is also somewhat less clear, even when max is a constant. &lt;/p&gt;

&lt;p&gt;4 . In some cases there is no way the compiler could correctly guess the intent from the declaration and you have to use a vendor-specific attribute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vhdl"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;ram_t&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="mi"&gt;63&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="kt"&gt;std_logic_vector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;signal&lt;/span&gt; &lt;span class="n"&gt;ram&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ram_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;attribute&lt;/span&gt; &lt;span class="n"&gt;ramstyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;attribute&lt;/span&gt; &lt;span class="n"&gt;ramstyle&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;ram&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;signal&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="s1"&gt;"MEMORY BLOCK"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this attribute set, the compiler would utilize the embedded block memory the device might have, and without it, it would have just wasted a lot of precious registers.&lt;/p&gt;

&lt;p&gt;Undoubtedly there are a lot more cases, but you get the idea.&lt;/p&gt;

&lt;p&gt;Another thing, which may not be a pattern per se, but is similar in concept, and made an important paradigm shift for me was about functions. In software we think of a function as of some kind of generator, something that &lt;em&gt;takes&lt;/em&gt; inputs and &lt;em&gt;produces&lt;/em&gt; output. As if a new object is instantiated inside the function from the input arguments and returned as a new entity.&lt;/p&gt;

&lt;p&gt;VHDL functions should be read differently - all they do is &lt;em&gt;transform&lt;/em&gt; input signals to output signals. This way, a VHDL function is a wiring fragment, not a generator. So where in C you had&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// create a new int and return it&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in VHDL you have&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vhdl"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;integer&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt;
&lt;span class="k"&gt;begin&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;-- wire a and b together and stick new wires out&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and from this observation there is just one step to looking at VHDL code like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;all VHDL code is just wire fragments decoupled by registers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next, I'd like to give you the most important pattern of all, &lt;em&gt;the component itself&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;You see, most of the components that you have look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vhdl"&gt;&lt;code&gt;&lt;span class="k"&gt;entity&lt;/span&gt; &lt;span class="n"&gt;edge_detector_with_passthrough&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt;
    &lt;span class="k"&gt;port&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;clk&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;      &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kt"&gt;std_logic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;i_input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kt"&gt;std_logic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;o_output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;std_logic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;o_edge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;std_logic&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="n"&gt;edge_detector_with_passthrough&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;architecture&lt;/span&gt; &lt;span class="n"&gt;mixed&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;edge_detector_with_passthrough&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt;

    &lt;span class="k"&gt;signal&lt;/span&gt; &lt;span class="n"&gt;b_input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;std_logic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;begin&lt;/span&gt;

    &lt;span class="n"&gt;o_output&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;i_input&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;process&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt;
    &lt;span class="k"&gt;begin&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;rising_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;

            &lt;span class="n"&gt;b_input&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;i_input&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;o_edge&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="sc"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i_input&lt;/span&gt; &lt;span class="o"&gt;/=&lt;/span&gt; &lt;span class="n"&gt;b_input&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
                &lt;span class="n"&gt;o_edge&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="sc"&gt;'1'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;process&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="n"&gt;mixed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the reason for this is, lacking better form of expression, by writing the code &lt;em&gt;in this exact way&lt;/em&gt;, we telegraph our intent to the compiler. Specifically, in the above code, when we write&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vhdl"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;rising_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it doesn't mean that we are interested in the actual edge of the clock signal. Instead, we mean that &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;everything that happens inside that "if" is supposed to be synchronized with the clock signal (i.e. registered) &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you look closely, you see that there are two identically &lt;em&gt;looking&lt;/em&gt; signal assignments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vhdl"&gt;&lt;code&gt;&lt;span class="n"&gt;o_output&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;i_input&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;b_input&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;i_input&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but when the first one resides in a combinatorial (i.e. unregistered) area of the component, it gets translated to a direct wire, the second happens to be inside the synchronized block and therefore &lt;em&gt;a register is inferred&lt;/em&gt; between b_input and i_input. Similarly o_edge becomes registered just by the fact of being assigned from inside the registered block. Which gives you the following diagram:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbp1gj1jc9a5rs9mqlxtk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbp1gj1jc9a5rs9mqlxtk.png" alt="Alt Text" width="798" height="589"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, there is a case when it's not even what you wrote that affects the the compiler output, but &lt;em&gt;what you didn't write&lt;/em&gt;. I'm talking about latches.&lt;/p&gt;

&lt;p&gt;The following fragment&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vhdl"&gt;&lt;code&gt;&lt;span class="k"&gt;architecture&lt;/span&gt; &lt;span class="n"&gt;latched&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;latch&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt;
&lt;span class="k"&gt;begin&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i_enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'1'&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="n"&gt;o_output&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;i_input&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="n"&gt;latched&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is hardly worth a second look, but is actually a quite important case of a missing "else". There is no else, you see. From software perspective, it's perfectly normal, if you do nothing, nothing happens.&lt;/p&gt;

&lt;p&gt;But as this code resides in the combinatorial area of the component, it describes direct wiring of signals and reads "if enable is high, pass input to output". But what happens to output otherwise ? Unlike in software, &lt;em&gt;nothing&lt;/em&gt; cannot happen in hardware. Output must be provided in any case, and if enable is low, we need to keep the &lt;em&gt;previous&lt;/em&gt; input somewhere and pass it to output, to create an illusion that "nothing happened". Therefore, in this case a &lt;em&gt;latch&lt;/em&gt; is inferred to hold the signal while enable is low.&lt;/p&gt;

&lt;p&gt;The moral here is that VHDL makes writing clear programs quite problematic. There is no domain-specific syntax in the language and no first class objects. Therefore, rather than simply declaring the intent, you have to second guess the compiler and write spell-like constructs.&lt;/p&gt;

&lt;p&gt;Why it turned out this way, I could guess that back in the days Ada was some kind of a military standard language, and when a committee decided what to use for VHDL, they did what committees do best - stick to the standards. Alas.&lt;/p&gt;

&lt;p&gt;Anyway, thank you for reading and I'll be happy to talk to you later.&lt;/p&gt;

</description>
      <category>vhdl</category>
      <category>fpga</category>
      <category>hardware</category>
      <category>programming</category>
    </item>
    <item>
      <title>Learning FPGA programming, key points for a software developer (part 2, registered logic)</title>
      <dc:creator>Dmitry Dvoinikov</dc:creator>
      <pubDate>Mon, 27 Jul 2020 13:01:56 +0000</pubDate>
      <link>https://forem.com/targeted/learning-fpga-programming-key-points-for-a-software-developer-part-2-registered-logic-j3k</link>
      <guid>https://forem.com/targeted/learning-fpga-programming-key-points-for-a-software-developer-part-2-registered-logic-j3k</guid>
      <description>&lt;p&gt;The &lt;a href="https://dev.to/targeted/learning-fpga-programming-key-points-for-a-software-developer-18bf"&gt;first part&lt;/a&gt; of this article discussed the importance of time in an electrical circuit, of which a VHDL program is a schematic. You may want to read it before proceeding.&lt;/p&gt;

&lt;p&gt;As a summary, an electrical circuit depends on the coordinated delivery of its input signals, before it could produce a valid output.&lt;/p&gt;

&lt;p&gt;On the face of it, we could wire any number of circuits together, activate the top-level inputs, and then just wait for the entire maze to flush through and yield stable output after some time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe92k06vn6ph0f465s9k0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe92k06vn6ph0f465s9k0.png" alt="Alt Text" width="800" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It could work for some circuits, and when it does work, this approach is the fastest, I guess, because it's basically limited with the speed of light. But it doesn't work in all cases.&lt;/p&gt;

&lt;p&gt;One reason why it doesn't, is that circuits can be so twisted that they simply won't stabilize over time, and never provide output.&lt;/p&gt;

&lt;p&gt;The simplest such case is a feedback loop, when a circuit's output is directly or indirectly plugged into its input. Under such conditions, the circuit could go into an indeterminate state forever.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flj33rj7z9qn7vw2fevxl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flj33rj7z9qn7vw2fevxl.png" alt="Alt Text" width="748" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A combinatorial approach whereby you just wire blocks together thus has its limits. And the problem of stable inputs arriving to a circuit at the same time is still there. How is it solved ?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To ensure that the signals that cross boundaries between combinatorial blocks are stable and synchronous, they are held in a buffer between the blocks, until all of them arrive and stabilize. This buffer is called &lt;em&gt;register&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvpm521uo594a28qmuwm5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvpm521uo594a28qmuwm5.png" alt="Alt Text" width="664" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This looks good but now we have a different problem. How does the register know for how long to hold its input and when to pass it through ? It is nothing but a wired circuit itself after all.&lt;/p&gt;

&lt;p&gt;To solve it, a clock is introduced. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A clock is an external source of a periodic pulse, connected to every register in the system with a dedicated line. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Femet2bj74ytjn3bg1cai.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Femet2bj74ytjn3bg1cai.png" alt="Alt Text" width="681" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All the registers in the system pass their input to output at clock tick, thus conceptually at the same time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When we decouple multiple combinatorial circuits with registers, we get a bigger &lt;em&gt;registered&lt;/em&gt; or &lt;em&gt;synchronous&lt;/em&gt; circuit. The are two important things to observe about it.&lt;/p&gt;

&lt;p&gt;First, there is still no guarantee that clock tick arrives at the moment when output is stable, because combinatorial circuits generate it asynchronously, with no respect to any clock. This will still fail to pass the correct value:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk3jlwh7cf1bkg2cmixsj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk3jlwh7cf1bkg2cmixsj.png" alt="Alt Text" width="661" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make sure it does not happen, the combinatorial components must play by the clock rules and have their outputs stabilized after the last tick, but before the next. This effectively means two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;They should only accept registered signals for their inputs. Any input signal not synchronized with the same clock is a risk to stability.&lt;/li&gt;
&lt;li&gt;They must be simple enough to propagate the signal in the limited time they have between the clock ticks.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fz6fjmgo31blpgx19iaaw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fz6fjmgo31blpgx19iaaw.png" alt="Alt Text" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Second, the earliest moment when a value will appear at the other side of the register is at the start of next tick, even though it became available long before that.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fda8s2nmlgdmmlnt38csn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fda8s2nmlgdmmlnt38csn.png" alt="Alt Text" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Therefore a registered circuit makes a pipeline, in which signal values propagate one leg at a time, and not immediately from start to finish as before. And the earliest moment when a sequence of N registered components will produce the final output is N times tick duration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ft0zq2dni8lciy9ko6xq8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ft0zq2dni8lciy9ko6xq8.png" alt="Alt Text" width="731" height="211"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the above pipeline you could see that we get in 300 nanoseconds what we could otherwise get in 3, and if we wait for the output, then at any time 3/4 of the circuit is not doing any productive job. That's a lot of waste but it is the price to pay for stability.&lt;/p&gt;

&lt;p&gt;Now, this was all about hardware. &lt;/p&gt;

&lt;p&gt;From the software developer's perspective, there are a few things to notice.&lt;/p&gt;

&lt;p&gt;The most important thing is that when you are working with registered signals, you are, figuratively speaking, turning yesterday's values into tomorrow's values.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Any registered signal assignment will have effect only in the next tick, even observed by the same component. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhy4fnm2e4jkluvtaehth.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhy4fnm2e4jkluvtaehth.png" alt="Alt Text" width="671" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another important thing is that &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;registered signal exchange between components takes very significant amount of time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In software, we assume that calls take no time compared to the processing. We factor our programs freely into processing modules of all kinds, components, classes, functions, along the domain objects, and call one from another without second thought. But in hardware, it's the opposite: processing happens at the speed of light, but every registered signal exchange adds an extra clock cycle, thus decimating the performance. &lt;/p&gt;

&lt;p&gt;Consider the following simplest case of client-server exchange. The client waits for a ready signal from the server, then sends a request and waits for a response.&lt;/p&gt;

&lt;p&gt;Here is the code sample:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Faeqtlui7t53pcwpamg1z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Faeqtlui7t53pcwpamg1z.png" alt="Alt Text" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Its timing diagram:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fn00ucnad6ieoyejdgk2i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fn00ucnad6ieoyejdgk2i.png" alt="Alt Text" width="673" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the legend:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Both the client and the server come out of reset and the server &lt;em&gt;immediately&lt;/em&gt; asserts ready.&lt;/li&gt;
&lt;li&gt;The client sees that the server is ready and &lt;em&gt;immediately&lt;/em&gt; provides the input.&lt;/li&gt;
&lt;li&gt;The server sees the input and &lt;em&gt;immediately&lt;/em&gt; responds.&lt;/li&gt;
&lt;li&gt;The client sees the response and &lt;em&gt;immediately&lt;/em&gt; passes it on.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As you can see, despite all the reactions being immediate, the registers only pass the updated value signal at the next tick. Therefore, should you have inlined the calculation in the client, it would have been immediate, but when you delegate it to a different registered component, it takes 4 clock cycles.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Factoring a VHDL program into components should be based on physical composition, not on logical delegation. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Another thing, in software, the basic concept is that code is executed by a thread, a logical entity that follows the code like a vinyl player needle. And then we could start any number of threads playing the same record independently.&lt;/p&gt;

&lt;p&gt;In hardware it is once again the opposite. Now it is &lt;em&gt;the values&lt;/em&gt; that flow through the program, and it is the front of that wave that &lt;em&gt;is&lt;/em&gt; its current state. You can't just run a second wave through the same wires, they will cancel each other. To increase parallelism in a registered circuit, we notice that every register holds the flow like a floodgate. Then it is possible to have multiple waves coming one after another, separated by as much as a single tick and they will not conflict.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzd3wjnm5ioz60hpdvx6z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzd3wjnm5ioz60hpdvx6z.png" alt="Alt Text" width="619" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, from the most basic coding standpoint, registers are invisible. Just like the flow of time from the &lt;a href="https://dev.to/targeted/learning-fpga-programming-key-points-for-a-software-developer-18bf"&gt;first part&lt;/a&gt; of this article, they do not appear in the code. And you just have to see them where they are supposed to be, to understand how the circuit behaves. I will address this in more details in the next part of this article:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/targeted/learning-fpga-programming-key-points-for-a-software-developer-part-3-code-patterns-and-inferred-behavior-1j28"&gt;Part 3: Code patterns and inferred behavior&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you for reading !&lt;/p&gt;

</description>
      <category>fpga</category>
      <category>vhdl</category>
      <category>hardware</category>
      <category>programming</category>
    </item>
    <item>
      <title>Learning FPGA programming, key points for a software developer (part 1, the time)</title>
      <dc:creator>Dmitry Dvoinikov</dc:creator>
      <pubDate>Tue, 21 Jul 2020 11:27:47 +0000</pubDate>
      <link>https://forem.com/targeted/learning-fpga-programming-key-points-for-a-software-developer-18bf</link>
      <guid>https://forem.com/targeted/learning-fpga-programming-key-points-for-a-software-developer-18bf</guid>
      <description>&lt;p&gt;It may be difficult for a software developer to pick up FPGA hardware programming. Here I explain a few important concepts that I wish someone had explained to me.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.linkedin.com/pulse/hello-fpga-world-dmitry-dvoinikov" rel="noopener noreferrer"&gt;This post&lt;/a&gt; began my FPGA journey as an absolute beginner that I then was.&lt;/p&gt;

&lt;p&gt;Several months later, a dozen books read, couple of very simple toy projects worked upon, a bunch of devices experimented with, I have better understanding of why it was so difficult, and would like to share the experience with you.&lt;/p&gt;

&lt;p&gt;All of it may be in the books, but the books tend to either assume the electrical engineering background or stay clear off the hardware territory. Either way, it does not help a software developer. It was an occasional diagram here or a stray sentence there that lit the bulb for me. The few concepts I found most important and try to explain as clear as I can from a software developer's perspective.&lt;/p&gt;

&lt;p&gt;There are three parts in this article. This first part is about the concept of &lt;em&gt;time&lt;/em&gt;. The second part is about &lt;a href="https://dev.to/targeted/learning-fpga-programming-key-points-for-a-software-developer-part-2-registered-logic-j3k"&gt;registered logic&lt;/a&gt;, and the third - &lt;a href="https://dev.to/targeted/learning-fpga-programming-key-points-for-a-software-developer-part-3-code-patterns-and-inferred-behavior-1j28"&gt;code patterns and inferred behavior&lt;/a&gt;. A minimal VHDL knowledge is expected from the reader.&lt;/p&gt;

&lt;p&gt;VHDL is not a regular (imperative) programming language. A program in VHDL is not a sequence of instructions to be executed by some underlying machine. VHDL program is a schematic of a circuit. Nothing moves there, nothing is "executed". Once VHDL program is compiled, the circuit is quite literally cast in copper, and then only electric current flows through the wires.&lt;/p&gt;

&lt;p&gt;Let me repeat. There is nothing there but &lt;em&gt;electric wires&lt;/em&gt;. The entire purpose of the circuit that you build is to transform input signals into output signals in a specific manner. So that the following VHDL fragment&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vhdl"&gt;&lt;code&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;compiles into&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0ys5tzo9ph40ky4tzaym.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0ys5tzo9ph40ky4tzaym.png" alt="Alt Text" width="630" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For this simple example it may look obvious, but here is another one, what do you think happens when you compile&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vhdl"&gt;&lt;code&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;?&lt;/p&gt;

&lt;p&gt;This:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcg4ptct20cybr3nv88pa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcg4ptct20cybr3nv88pa.png" alt="Alt Text" width="603" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Number theory is well explored and the multiplication algorithms may be known, but the resulting circuit is still a twisted mile of wires. It is so complicated because from the assignment that we wrote it appears that we wanted the product output to appear on the wire &lt;em&gt;at the same time&lt;/em&gt; as the inputs are set.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The biggest hurdle of hardware programming is time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Time means very different thing in hardware, than it does in software. For a software developer writing a program, time flows from one line of code to the next, each line happening conceptually in a separate instant. We read it as "and then ...".&lt;/p&gt;

&lt;p&gt;For example, as a software developer, what could you say about time in the following C-like code fragment ?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9d9y731eyu72rwizz1x2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9d9y731eyu72rwizz1x2.png" alt="Alt Text" width="800" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most likely your intuition will tell you that instant 1 &amp;lt; instant 2 &amp;lt; instant 3 (execution order) and duration 1 ~ duration 2 &amp;lt; duration 3 (estimated complexity) and that's about as much as we typically care about time in software world.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In a regular program time flows down and the lines are executed in order. In VHDL the flow of time is orthogonal, it flows along the lines, while the lines themselves happen at the same time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's look at the simplest VHDL fragment again:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ften6tncv4vbz784vqeiy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ften6tncv4vbz784vqeiy.png" alt="Alt Text" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you realize that each assignment is a transmission of a signal over a wire, it becomes even more interesting.&lt;/p&gt;

&lt;p&gt;First, it's not even an "assignment" in a variable sense, the outputs are not "assigned". They just repeat the input after a short delay. It makes no difference if it is a one, zero, or a sine wave:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbz0ofefga1bzixp8aqmp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbz0ofefga1bzixp8aqmp.png" alt="Alt Text" width="800" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then there is an issue of "same time". It takes time for the signals to propagate through the wires and the propagation delays vary. Remember the multiplication mess ? If you look closely, it appears that the integers being multiplied are actually represented as one wire per bit, and different bits take different paths through the circuit:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv7kwolrwlcnvr6punled.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv7kwolrwlcnvr6punled.png" alt="Alt Text" width="774" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Therefore, even if all the input bits were asserted at the same time, the output bits may get out at different times. The nanosecond difference may sound small, but it is real, it accumulates, and becomes crucial, when you realize that one circuit's output is another's input:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuewhmt85ria25lwwvxs8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuewhmt85ria25lwwvxs8.png" alt="Alt Text" width="788" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then here is the critical question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How does a circuit know when its inputs are ready ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It doesn't. Depending on when and in which order the input signals arrive, the circuit's output will go through transitions, some of which are useless, and some could even be semantically impossible. The output of the second circuit will therefore be garbage, before the inputs have settled. It is only after the inputs are stable plus some internal delta, when a circuit's output makes sense.&lt;/p&gt;

&lt;p&gt;You can combine any number of circuits by wiring them together (this is called &lt;em&gt;combinatorial&lt;/em&gt; in VHDL), but you have to pay attention to the timings and signal propagation, to know which signal arrives to its destination when, and when the output actually becomes usable.&lt;/p&gt;

&lt;p&gt;Time flow is therefore the most important part of VHDL program. It is not mentioned in the actual code for the most part, but you just have to see it there to be able to reason about the circuit's behavior.&lt;/p&gt;

&lt;p&gt;Thank you for reading, and the next parts of this article discuss:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/targeted/learning-fpga-programming-key-points-for-a-software-developer-part-2-registered-logic-j3k"&gt;Part 2: Registered logic&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/targeted/learning-fpga-programming-key-points-for-a-software-developer-part-3-code-patterns-and-inferred-behavior-1j28"&gt;Part 3: Code patterns and inferred behavior&lt;/a&gt;&lt;/p&gt;

</description>
      <category>fpga</category>
      <category>vhdl</category>
      <category>hardware</category>
      <category>programming</category>
    </item>
    <item>
      <title>Password keeping devices. Comparison of YubiKey vs. OnlyKey</title>
      <dc:creator>Dmitry Dvoinikov</dc:creator>
      <pubDate>Tue, 28 May 2019 11:36:48 +0000</pubDate>
      <link>https://forem.com/targeted/password-keeping-devices-comparison-of-yubikey-vs-onlykey-4gpi</link>
      <guid>https://forem.com/targeted/password-keeping-devices-comparison-of-yubikey-vs-onlykey-4gpi</guid>
      <description>&lt;p&gt;There’s just a couple of problems with passwords.&lt;/p&gt;

&lt;p&gt;First, we need them to be strong. Some 12 random characters or more. No matter if you use a password manager, trust a small company to store all your passwords in a cloud, or a big corporation to track all your logins at all, you still need a master password, and it’d better be double strong now. You can use biometrics as an alternative to the master password on your laptop, but this effectively binds you to it.&lt;/p&gt;

&lt;p&gt;Second, there still are cases when you absolutely have to type the password manually. Basically, everything outside of desktop. One such case is full disk encryption at boot loader prompt. Or a login on an important console. And this is exactly when you need the strongest passwords.&lt;/p&gt;

&lt;p&gt;But can you remember a single truly strong password ? I can’t.&lt;/p&gt;

&lt;p&gt;In this article I’m going to analyze and compare two hardware devices that remember your passwords and type them for you.&lt;/p&gt;

&lt;p&gt;Specifically, &lt;a href="https://www.yubico.com/" rel="noopener noreferrer"&gt;YubiKey&lt;/a&gt; and &lt;a href="https://onlykey.io/" rel="noopener noreferrer"&gt;OnlyKey&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;YubiKey is a Xerox of authentication devices, their products come in all shapes and sizes, connectable via different ports, also with wireless support. From now on I will refer as just a YubiKey to the one device that I have, namely &lt;a href="https://support.yubico.com/support/solutions/articles/15000006492-yubikey-edge" rel="noopener noreferrer"&gt;YubiKey Edge&lt;/a&gt;. It is a simple full size USB dongle, no NFC. OnlyKey is a new contender and they have just one product which is also a full size USB dongle.&lt;/p&gt;

&lt;p&gt;I will also focus exclusively on using both in “first factor static password” mode. Despite both supporting multiple second factor modes, I’ve found it impractical to use them as a second factor. A smartphone or a dedicated $5 dongle is a better option for that.&lt;/p&gt;

&lt;p&gt;That out of the way, let’s begin.&lt;/p&gt;

&lt;p&gt;In concept, both devices are identical, and the idea behind them is beautiful in its simplicity. They are essentially external keyboards in a USB dongle form. You press a button on the dongle, it spits out the password as if someone typed it on a keyboard. That’s it.&lt;/p&gt;

&lt;p&gt;Here they are side by side:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HMTNpil2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/z55xh1b8v4etwalh6j0p.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HMTNpil2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/z55xh1b8v4etwalh6j0p.jpg" width="800" height="634"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The elephant in the room is of course the number of buttons. YubiKey has one, OnlyKey has six. I will address it under Features.&lt;/p&gt;

&lt;h3&gt;
  
  
  First impression and ergonomics
&lt;/h3&gt;

&lt;p&gt;Manufacturing quality is impeccable on both devices.&lt;/p&gt;

&lt;p&gt;YubiKey feels more like a consumer utility, it is a perfectly rugged piece of plastic, something that you can forget in a pocket of your jeans being washed and it still works.&lt;/p&gt;

&lt;p&gt;OnlyKey feels more like a serious security device, it is cut from a piece of PCB, you can see all the circuitry laminated in a transparent epoxy, and there is a separate rubber sleeve that you are supposed to put on after you have finished looking at it. It is also larger and thicker.&lt;/p&gt;

&lt;p&gt;Buttons on both devices are not really buttons. They are copper plates that you touch, not push. No tactile feedback, but they last.&lt;/p&gt;

&lt;h3&gt;
  
  
  Features
&lt;/h3&gt;

&lt;p&gt;YubiKey is extremely simple. It can store two passwords. Since there is only one button, you choose which password to type by touching the button momentarily or for longer than two seconds.&lt;/p&gt;

&lt;p&gt;OnlyKey is way more complex. It has a large LED that changes color and blinks differently, depending on what the device does. It has six buttons and can store 24 passwords. Given six buttons and the same two-seconds trick as with YubiKey, you get 12 passwords. And there are two different user profiles, a total of 24.&lt;/p&gt;

&lt;p&gt;But the crucial difference between the two is that OnlyKey is itself password protected. You need to punch in a correct PIN after plugging it. The LED goes green and the device is ready to use. This is a major security benefit. You can leave OnlyKey anywhere and not worry who touches it. YubiKey you need to keep an eye on at all times.&lt;/p&gt;

&lt;p&gt;Another big plus for OnlyKey is that it is way more configurable. Each of 24 entries you can set up in such a manner that it types, for example, URL, ENTER, 3 seconds pause, username, TAB, password and finally ENTER. Not just password.&lt;/p&gt;

&lt;p&gt;There are other OnlyKey features that indicate that its makers indeed wanted a security device, not a consumer utility. So for example you can set up a fake PIN which could be entered under duress upon which the device erases itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  Usability in the field
&lt;/h3&gt;

&lt;p&gt;YubiKey just works. It’s perfectly simple, not much else to say. You plug it in, it’s ready in three seconds, touch the button, and away it goes.&lt;/p&gt;

&lt;p&gt;OnlyKey takes the same three seconds to boot, but then you also need to punch your PIN, which takes another four seconds, then another three seconds to decrypt before it goes green. It feels slow, but not terribly slow.&lt;/p&gt;

&lt;p&gt;When you plug the OnlyKey to a side port of a laptop, the buttons on the OnlyKey are too close to the edge of the keyboard. It happens, although not very often, that I accidentally touch a button with the edge of a palm, and it types in the password unexpectedly. That’s a nuisance that can become a very serious security leak. You may need to be unplugging the device each time, or plugging it to a port not so easily accessible.&lt;/p&gt;

&lt;p&gt;There is also an issue with the entire class of such devices, and it is that they send in not characters, but scan codes, meaning they imitate key presses at the keys located in certain positions of the keyboard. What's the difference ? When an international layout is activated, such as Russian or German, what you get in the password is the sequence of Cyrillic letters, or have some letters (Z vs. Y) swapped. This is especially annoying when you plug the device to a phone, it is recognized as an external keyboard and the on-screen keyboard disappears, making it impossible to switch the layout.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;p&gt;Both devices are programmable each using a companion application. The applications do the job, but as far as usability goes are nothing but a column of checkboxes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ENXqoy8w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/0uvoahy6qc4qazobzu3s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ENXqoy8w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/0uvoahy6qc4qazobzu3s.png" width="800" height="659"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5l8-GzNB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/psfw5x0ef8s0vx22a0s7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5l8-GzNB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/psfw5x0ef8s0vx22a0s7.png" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Platform compatibility
&lt;/h3&gt;

&lt;p&gt;The inevitable question - is it possible to use such devices with different platforms ? Both devices that I have work perfectly with Windows and Linux, also at boot loader prompt. They also worked for me with Apple devices via a Lightning-to-USB adapter.&lt;/p&gt;

&lt;p&gt;Mobile, it’s not rosy for YubiKey. YubiKey devices seem to only support second factor over NFC, not static password, and my Android smartphone does not recognize YubiKey as an external keyboard when plugged in. What it does recognize is OnlyKey, and it is absolutely usable with Android.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Both devices I could highly recommend. Appearance aside, here is the takeout:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;YubiKey is better, because it’s easier to use. And the manufacturer provides different devices that might work in your case. It is worse, because it only remembers two passwords, and they are not secured by the device.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OnlyKey is better, because it remembers a lot of not just passwords but entire arbitrary login scenarios, and they are all stored securely. It is worse, because it is not quite as easy to use.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you so much for reading !&lt;/p&gt;

</description>
      <category>security</category>
      <category>hardware</category>
      <category>yubikey</category>
      <category>onlykey</category>
    </item>
  </channel>
</rss>
