<?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 &#187; perl</title>
	<atom:link href="http://billauer.se/blog/tag/perl/feed/" rel="self" type="application/rss+xml" />
	<link>https://billauer.se/blog</link>
	<description>Anything I found worthy to write down.</description>
	<lastBuildDate>Thu, 12 Mar 2026 11:36:00 +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>Using Perl to map FPGA pins from a board design to UCF pin constraints</title>
		<link>https://billauer.se/blog/2009/03/perl-script-netlist-ucf-orcad-schematic/</link>
		<comments>https://billauer.se/blog/2009/03/perl-script-netlist-ucf-orcad-schematic/#comments</comments>
		<pubDate>Thu, 26 Mar 2009 23:42:03 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[FPGA]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[board design]]></category>
		<category><![CDATA[netlist]]></category>
		<category><![CDATA[PCB]]></category>
		<category><![CDATA[pinout]]></category>
		<category><![CDATA[UCF]]></category>
		<category><![CDATA[User Constraint File]]></category>
		<category><![CDATA[Xilinx]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=72</guid>
		<description><![CDATA[One of the things I try to avoid as an FPGA engineer, is to manually configure the pin constraints (in the UCF file) in order to tell the tools which FPGA pin is connected to what. Not only is this extremely boring, but I also think that getting it done right (at the first go) [...]]]></description>
			<content:encoded><![CDATA[<p>One of the things I try to avoid as an FPGA engineer, is to manually configure the pin constraints (in the UCF file) in order to tell the tools which FPGA pin is connected to what. Not only is this extremely boring, but I also think that getting it done right (at the first go) is more or less a miracle.</p>
<p>If you insist on working with the Orcad schematics, you&#8217;re doomed. Yes, this graphical representation of the board is useful for getting an idea of what&#8217;s going on. But when I want to know for sure what is connected to what on the PCB, I read the netlist file. It&#8217;s that text file, which the board designer sends to the PCB manufacturing plant. So even if schematics is convincing, what counts is what the netlist file says. Sometimes reading the netlist reveals connections which were not obvious at all from looking at the schematics. But I&#8217;m diverting from the point, which is how to generate the UCF file sort-of automatically. Or at least spare most of the work.</p>
<p>So let&#8217;s have a look on what a netlist file looks like. This is a snippet from the middle, where the precious information is:</p>
<pre>SIN_D8  = U43/V5 U48/42 ;
CLK_SEL  = R393/1 U52/36 ;
N14463023  = U29/7 R154/1 R326/2 ;
N16132557  = U64/1 C589/1 L90/1 L91/1
            C594/1 U64/2 ;
SOUT_A_A9  = U38/34 U43/AB21 ;
SENSOR_B_D3  = U43/N8 U49/11 ;
SIN_D9  = U43/U4 U48/44 ;</pre>
<p>So the structure is very simple. A statement begins with the net&#8217;s name, an equation sign and then a listing of the connected pins. As you can see, each statement is terminated by a semicolon, and may consist of several lines.</p>
<p>The nets&#8217; names are given by the board designer manually. There is no assurance that this name has anything to do with what the net is connected to, so if you&#8217;re really pedantic, you should verify that as well. Checking the schematics is fairly efficient, or you could verify the pin connections in the netlist, which may be fairly easy with some scripting skills.</p>
<p>Also, if no name was given to the net, but it&#8217;s a result of just connecting two pins, Orcad will make up a name, which usually looks something like N16132557. A common, and annoying case is when there is a resistor between two chips&#8217; pins (say, for debouncing). Because of the resistor in the middle, two nets make the connection. If the board designer gives the name to the net between the FPGA and the resistor, we get the name for free. If not, we need to be smarter.</p>
<p>And that brings us to the pin listing  in the netlist. If we take the SOUT_A_A9 net for example, we can see that it&#8217;s connecting between pin 34 of device marked U38, and pin AB21 of U43. On this specific board, U43 happens to be the FPGA.</p>
<p>This leaves us with two possible strategies. One is to trust the net&#8217;s name, and make an entry in the UCF file, which binds pin AB21 to a Verilog/VHDL toplevel I/O port with a similar name, say &#8220;sout_a_a[9]&#8220;.  I&#8217;ll show an example script for this below.</p>
<p>The second strategy would try to find out what pin 34 of U38 stands for, and give the port&#8217;s name accordingly. This is trickier, of course, but given a reliable pin mapping of the other chip, this neutralizes any mistake possibly made by the board designer. This is where I&#8217;d like to mention, that certain board design tools create a &#8220;chip file&#8221;, which is a text file as well. This text file contains meaningful names for each chip included in the design (these are, in fact, the names that appear on the schematics). This file&#8217;s name is typically pstchip.dat. Unfortunately, the information in this file is commonly fed manually from a datasheet at some stage of the board design, so if an error was made during this stage, both the board and the FPGA pinout will get it wrong.</p>
<p>But let&#8217;s leave the pessimism for a while, and assume that we can rely on the nets&#8217; names. Here&#8217;s a script, which finds the FPGA&#8217;s connections, an attempts to create a UCF file. Please keep in mind that it&#8217;s just an example, and that it doesn&#8217;t cover all nets even in the design I wrote it for. If you want to use this technique in your own designs, you&#8217;ll have to adapt it to the quirks of the netlist you&#8217;re facing.</p>
<p>Anyhow, here it is:</p>
<pre>#!/usr/bin/perl
use warnings;
use strict;

undef $/; # Slurp mode. (Sane people use "local" instead)
my $file = &lt;&gt;;

my @chunks = ($file =~ /^([^ %].+?);/gsm);
my @out;

foreach my $chunk (@chunks) {
  my ($var, $rest) = ($chunk =~  /^([^ ]+)[ ]*=[ ]*(.*)/s);
  die("Failed to read line: $chunk\n")
    unless (defined $var);
  next if (grep { $_ eq lc $var }
	   qw[vcc_int vcc_aux v3_3 gnd]);
  my @pins = ($rest =~ /U43\/([^ \n\r\t]+)/gi);
  push @out, "NET \"".(lc $var)."\" LOC = \"$_\";\n" foreach (@pins);
}
print sort @out;</pre>
<p>Just a few clarifications: U43 is the FPGA in my netlist, right? So that&#8217;s why I filter out anything else. And now a few Perl clarifications.</p>
<ul>
<li>I begin with undeffing $/. This makes the single &#8216;$file=&lt;&gt;&#8217; statement read the entire file at once (that&#8217;s why they call it slurp mode). The Perl manpage encourages to use &#8220;local&#8221; instead of &#8220;undef&#8221;, and it explains why, but it&#8217;s not relevant for a short script.</li>
<li>The first regular expression (feeding @chunks) cuts the file into pieces between semicolons.</li>
<li>The second regular expression splits each chunk into the string before &#8216;=&#8217; (in $var) and everything that comes afterwards (in $rest, possibly longer than a single line).</li>
<li>The grep sentence checks if we&#8217;re not on a power net, which should be skipped.</li>
<li>The last regular expression looks for a &#8216;U43/&#8217;-something, and if that is found, the pins are stored in the @pins list (in a sane case, this will be only one pin, or we&#8217;re messed up)</li>
</ul>
<p>As I said before, I don&#8217;t really expect this script to work out of the box for you, but I hope I made the point about using a Perl script on a netlist to make life easier. And in case you&#8217;re an FPGA Engineer, and don&#8217;t know Perl, I hope this gave an idea of why you should start learning&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2009/03/perl-script-netlist-ucf-orcad-schematic/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Why MySQL&#8217;s (SQL) DATETIME can and should be avoided</title>
		<link>https://billauer.se/blog/2009/03/mysql-datetime-epoch-unix-time/</link>
		<comments>https://billauer.se/blog/2009/03/mysql-datetime-epoch-unix-time/#comments</comments>
		<pubDate>Sun, 15 Mar 2009 14:58:24 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[datetime]]></category>
		<category><![CDATA[epoch]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[time]]></category>
		<category><![CDATA[unix]]></category>
		<category><![CDATA[utc]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=34</guid>
		<description><![CDATA[I warmly recommend reading the comments at the bottom of this page, many of which go against my point. While I still stand behind every word I said, in particular for web applications (which I believe is the vast majority of MySQL use), the comments below make some valid points, and single out cases where [...]]]></description>
			<content:encoded><![CDATA[<div style="border: 2px solid #9b9; margin: 20px 5px 50px 5px; padding: 15px 5px 0 5px;"><i></p>
<p>I warmly recommend reading the comments at the bottom of this page, many of which go against my point. While I still stand behind every word I said, in particular for web applications (which I believe is the vast majority of MySQL use), the comments below make some valid points, and single out cases where DATETIME actually <b>is</b> the right thing.</p>
<p>
Needless to say, this is a discussion, and we&#8217;re all free to make our own mistakes.</p>
<p></i></div>
<h2>SQL DATETIME sucks</h2>
<p>MySQL, among other databases, has a column type called DATETIME. Its name seems to mislead people into thinking that it&#8217;s suitable for storing time of events. Or suitable for anything.</p>
<p>This is a general SQL thing, by the way, but I&#8217;ll demonstrate it on MySQL.</p>
<p>I often find this column type in other people&#8217;s database schemas, and I wonder if the designer gave it a thought before using it. It&#8217;s true, that in the beginning it looks simple:</p>
<pre>mysql&gt; CREATE TABLE stupid_date ( thedate DATETIME, PRIMARY KEY (thedate) );
Query OK, 0 rows affected (0.04 sec)

mysql&gt; INSERT INTO stupid_date(thedate) VALUES ( NOW() );
Query OK, 1 row affected (0.03 sec)

mysql&gt; SELECT * FROM stupid_date;
+---------------------+
| thedate             |
+---------------------+
| 2009-03-15 14:01:43 |
+---------------------+
1 row in set (0.00 sec)</pre>
<p>That was way too cute, wasn&#8217;t it? We also have the NOW() function, which fits in exactly, and puts the current time! Yay! Yay! And if the timestamp looks old-fashioned to you, I suppose there is a reason for that.</p>
<p>But wait, there are two major problems. The first one is that the time is given in the host&#8217;s local time. That was fair enough before the internet was invented. But today a web server can be a continent away. DATETIME will show you the local time of the server, not yours. There are SQL functions to convert timezones, of course. Are you sure that you want to deal with them? What happens when you want to move your database to a server in another timezone? What about daylight saving time? Local time is one big YUCK.</p>
<p><em>(Update: As commented below, the real stupidity is to use NOW(), and not UTC_TIMESTAMP(). The latter gives the UTC time, as its name implies)</em></p>
<p>Problem number two: Most applications don&#8217;t care what the absolute time is. The current time is commonly used to calculate how much time has elapsed since a certain event. To filter elements according to if they were X seconds before now. Is the user still logged in? Has 24 hours elapsed since the last warning email was sent? And so on.</p>
<p>&#8220;Solution&#8221;: The SQL language supplies a variety of COBOL-like functions to calculate whatever we can ask for. And also an opportunity to get things horribly wrong, because the SQL statement became way too complicated.</p>
<h2>Use POSIX time() instead</h2>
<p>Sorry, didn&#8217;t mean to scare you off. It&#8217;s really simple: Any modern operating system, even Windows, will readily supply you with the number of seconds since January 1, 1970, midnight, UTC (that is, more or less GMT). This is also called &#8220;seconds since the Epoch&#8221; or &#8220;UNIX time&#8221;.</p>
<p>No matter where the computer is, what timezone it uses or what programming language you&#8217;re using, this simple integer representation will show the same number at any given moment.</p>
<p>You can, in fact, obtain this number from MySQL directly:</p>
<pre>mysql&gt; SELECT UNIX_TIMESTAMP(thedate) FROM stupid_date;
+-------------------------+
| UNIX_TIMESTAMP(thedate) |
+-------------------------+
|              1237118503 |
+-------------------------+
1 row in set (0.00 sec)</pre>
<p>This means, that 1237118503 seconds elapsed since the Epoch (which is a global time point) until 14:01:43 in Israeli <span style="text-decoration: underline;">LOCAL time </span>of the day I wrote this post. So now we have an integer number to work with, which is handy for calculations, but things will still get messy if we try to move the database to another server.</p>
<h2>Store the number instead</h2>
<p>If we are interested in working with integers, why not store the integer itself in the database? We could go:</p>
<pre>mysql&gt; CREATE TABLE smart_date ( thedate INTEGER UNSIGNED, PRIMARY KEY (thedate) );
Query OK, 0 rows affected (0.00 sec)

mysql&gt; INSERT INTO smart_date(thedate) VALUES (1237118503);
Query OK, 1 row affected (0.00 sec)

mysql&gt; SELECT * FROM smart_date;
+------------+
| thedate    |
+------------+
| 1237118503 |
+------------+
1 row in set (0.00 sec)</pre>
<p>That wasn&#8217;t very impressive, was it? The first question would be &#8220;OK, how do I get this magic number, now that I don&#8217;t have the NOW() function?&#8221;</p>
<p>The short and not-so-clever answer is that you could always use MySQL&#8217;s UNIX_TIMESTAMP( NOW() ) for this. The better answer is that no matter which scripting or programming language you&#8217;re using, this number is very easy to obtain. I&#8217;ll show examples below.</p>
<p>As for the magnitude of this number, yes, it&#8217;s pretty big. But it will fit a signed 32-bit integer until year 2038. I presume that nobody will use 32-bit integers by then.</p>
<p>And finally, one could argue that DATETIME is convenient when reading from the database directly. True. But for that specific issue we have the FROM_UNIXTIME() function:</p>
<pre>mysql&gt; SELECT FROM_UNIXTIME(thedate) FROM smart_date;
+------------------------+
| FROM_UNIXTIME(thedate) |
+------------------------+
| 2009-03-15 14:01:43    |
+------------------------+
1 row in set (0.00 sec)</pre>
<p>And again, this is given in the computer&#8217;s local time. Which is fine, because it&#8217;s intended to be read by humans. In particular, humans who easily translate time differences between their server and themselves.</p>
<h2>Obtaining Epoch time</h2>
<p>Just to prove that it&#8217;s easy to know what the &#8220;Epoch time&#8221; is in any language, here are a few examples. Wherever it&#8217;s really simple, I&#8217;m showing how to convert this format to human-readable format.</p>
<p>In Perl:</p>
<pre>print time();
print scalar localtime time(); # Local time for humans</pre>
<p>In PHP:</p>
<pre>&lt;?php
echo time();
echo date('r', time() ); // Local time for humans
?&gt;</pre>
<p>In Python:</p>
<pre>from time import time;
print time();</pre>
<p>(note that the time is returned as a float number with higher precision)</p>
<p>In C:</p>
<pre>#include &lt;time.h&gt;
#include &lt;stdio.h&gt;

int main () {
  int now = time(NULL);

  printf("%d seconds since the Epoch\n", now);
  return 0;
}</pre>
<p>In JavaScript:</p>
<pre>&lt;script language="JavaScript" type="text/javascript"&gt;
now = new Date();
alert( now.getTime() / 1000 );
&lt;/script&gt;</pre>
<p>In this case, the time is shown with a fractional resolution.</p>
<p>The JavaScript example is not really useful for a database application, because the time is measured at the computer showing the page. In a website application, this is just anybody&#8217;s computer clock, which may be wrong. But it&#8217;s yet another example of how this time representation is widely available.</p>
<h2>Conclusion</h2>
<p>Drop those DATETIME columns from your tables, and use a simple, robust and handy format to represent time. Don&#8217;t let the database play around with a sensitive issue like time, and don&#8217;t risk getting confused by different functions when calculating time differences. Just because the DATETIME column type exists, it doesn&#8217;t mean there is a reason to use it.</p>
<p>Enjoy the database on what it&#8217;s best at: Storing and collecting information.</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2009/03/mysql-datetime-epoch-unix-time/feed/</wfw:commentRss>
		<slash:comments>93</slash:comments>
		</item>
	</channel>
</rss>
