<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7763117497297224225</id><updated>2012-01-26T08:37:11.118-08:00</updated><category term='linux'/><category term='arduino'/><category term='linuxmint'/><category term='RTL Visualiser'/><category term='programming'/><category term='sqlite'/><category term='asic design'/><category term='projects'/><category term='codecs'/><category term='openoffice'/><category term='csd'/><category term='Y-Placement'/><category term='asic verification'/><category term='hassle'/><category term='information management'/><category term='drivers'/><category term='python'/><category term='samba'/><category term='dcc'/><category term='verilog'/><category term='l293d'/><category term='pic'/><category term='very basic'/><category term='subversion'/><category term='systemverilog'/><title type='text'>Harnessing the Electron</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>21</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7763117497297224225.post-4437698266838497873</id><published>2011-01-19T18:18:00.000-08:00</published><updated>2011-01-19T19:15:50.023-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='arduino'/><category scheme='http://www.blogger.com/atom/ns#' term='dcc'/><title type='text'>DCC Firmware for Arduino</title><content type='html'>&lt;H2&gt;Firmware&lt;/H2&gt;So now that I had assembled the &lt;A HREF="http://amakersblog.blogspot.com/2011/01/controlling-model-trains-with-arduino.html"&gt;hardware&lt;/A&gt;, it was firmware time. I wanted to send an address:direction:speed string (eg "A001:F:S3") over the serial connection to the Arduino, and have the Arduino build the corresponding DCC packet and drive the H-Bridge accordingly.&lt;br /&gt;&lt;br /&gt;The Arduino &lt;A HREF="https://github.com/Harnesser/DCC-Controller"&gt;firmware&lt;/A&gt; I wrote to implement the DCC spec is interesting from two respects: it uses timer interrupts and it writes to the microcontroller ports directly. But I'm getting ahead of myself a little...&lt;H2&gt;DCC Specification&lt;/H2&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_nw9n44o883o/TTecEZqiOjI/AAAAAAAAABU/w03QumHDXL4/s1600/dcc_signal.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px; height: 92px;" src="http://1.bp.blogspot.com/_nw9n44o883o/TTecEZqiOjI/AAAAAAAAABU/w03QumHDXL4/s200/dcc_signal.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5564087464062237234" /&gt;&lt;/a&gt;Before going any further, we'd probably need to have a look at the DCC &lt;A HREF="http://www.nmra.org/standards/DCC/standards_rps/DCCStds.html"&gt;spec&lt;/A&gt;. DCC sends 1's and 0's as square waves of different lengths. A short square wave (58us * 2) represents a 1, and a longer one (&gt;95us * 2) is a 0.&lt;br /&gt;&lt;br /&gt;These 1's and 0's are then collected into packets and transmitted on to the rails. Each packet contains (at least):&lt;br /&gt;&lt;OL&gt;&lt;LI&gt;A preamble of eleven 1's&lt;/LI&gt;&lt;LI&gt;An address octet. This is the address of the train you want to control on the layout.&lt;/LI&gt;&lt;LI&gt;A command octet. This is 1 bit for direction and 7 bits for speed.&lt;/LI&gt;&lt;LI&gt;An error checking octet. This is the address octet XORed with the command octet&lt;/LI&gt;&lt;/OL&gt;Each of these sections is separated by a "0" and the packet ends with a "1" bit.&lt;br /&gt;&lt;br /&gt;If a train picks up a control packet that is not addresses to it, the command is ignored - the train keeps doing what it was last instructed to do, all the while still taking power from the rails. When nothing has to be changed, power must still be supplied to the trains so packets are still broadcast on the rails to supply power. In this case either the previous commands can be repeated or idle packets sent.&lt;br /&gt;&lt;H2&gt;Driving the H-Bridge&lt;/H2&gt;First, I had to figure out a way of driving the H-Bridge signals. Driving both legs of the H-Bridge incorrectly won't short out the power supply, but it will give ugly transitions on the rails ( &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_nw9n44o883o/TTeeZ_Dt4RI/AAAAAAAAABc/sNWhEXVo530/s1600/dcc_sparkline_bad.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 40px; height: 15px;" src="http://2.bp.blogspot.com/_nw9n44o883o/TTeeZ_Dt4RI/AAAAAAAAABc/sNWhEXVo530/s400/dcc_sparkline_bad.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5564090033900478738" /&gt;&lt;/a&gt; instead of &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_nw9n44o883o/TTeeaGLHkiI/AAAAAAAAABk/LQ2YlHB4vdk/s1600/dcc_sparkline_good.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 40px; height: 15px;" src="http://1.bp.blogspot.com/_nw9n44o883o/TTeeaGLHkiI/AAAAAAAAABk/LQ2YlHB4vdk/s400/dcc_sparkline_good.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5564090035810570786" /&gt;&lt;/a&gt;) and DCC decoders may not be able to decode the packet. The H-Bridge control signals should be driven differentially - both must change at the same time. This ruled out using &lt;CODE&gt;digital_write()&lt;/CODE&gt; to set pin states for two reasons: it can only change one pin at a time; and it's &lt;A HREF="http://www.billporter.info/ready-set-oscillate-the-fastest-way-to-change-arduino-pins/"&gt;too slow&lt;/A&gt;.&lt;br /&gt;&lt;br /&gt;So I needed to directly manipulate the a microcontroller digital port. I chose pins 11 and 12 which are both in &lt;A HREF="http://arduino.cc/en/Reference/Atmega168Hardware"&gt;PORTB&lt;/A&gt;. By &lt;A HREF="http://arduino.cc/en/Reference/PortManipulation"&gt;directly manipulating&lt;/A&gt; PORTB with a macro, I could now change the pins at the same instant in time.&lt;CODE&gt;&lt;PRE&gt;#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;#define DRIVE_1() PORTB = B00010000&lt;br /&gt;#define DRIVE_0() PORTB = B00001000&lt;br /&gt;&lt;/PRE&gt;&lt;/CODE&gt;When to use these macros was the next problem.&lt;br /&gt;&lt;H2&gt;Timing&lt;/H2&gt;As the DCC spec specifies quite a tight timing requirement on the 1 and 0 waveforms, I decided I should use the timer on the Arduino's microcontroller. Using the timer, I could place the transitions on the outputs accurately. So I set up the timer so that the interrupt would trigger every 58us. To simplify things, I defined the time of a 0 bit to be twice that of the 1 bit, ie 116us between transitions. For example, if I wanted to send a &lt;CODE&gt;1&lt;/CODE&gt;, I would drive &lt;CODE&gt;LO HI&lt;/CODE&gt;, and I'd drive &lt;CODE&gt;LO LO HI HI&lt;/CODE&gt; to transmit a &lt;CODE&gt;0&lt;/CODE&gt;. The timer setup routine is shown below.&lt;PRE&gt;void configure_for_dcc_timing() {&lt;br /&gt;  /* DCC timing requires that the data toggles every 58us&lt;br /&gt;  for a '1'. So, we set up timer2 to fire an interrupt every&lt;br /&gt;  58us, and we'll change the output in the interrupt service&lt;br /&gt;  routine.&lt;br /&gt;&lt;br /&gt;  Prescaler: set to divide-by-8 (B'010)&lt;br /&gt;  Compare target: 58us / ( 1 / ( 16MHz/8) ) = 116&lt;br /&gt;  */&lt;br /&gt;&lt;br /&gt;  // Set prescaler to div-by-8&lt;br /&gt;  bitClear(TCCR2B, CS22);&lt;br /&gt;  bitSet(TCCR2B, CS21);&lt;br /&gt;  bitClear(TCCR2B, CS20);&lt;br /&gt;  &lt;br /&gt;  // Set counter target&lt;br /&gt;  OCR2A = timer2_target;&lt;br /&gt;    &lt;br /&gt;  // Enable Timer2 interrupt&lt;br /&gt;  bitSet(TIMSK2, OCIE2A); &lt;br /&gt;}&lt;/PRE&gt;The interrupt service routine (ISR) for the timer is shown below. For accurate timing when using a count target for a timer, I have to reset the timer counter straight away. Straight after, I figure out which level I need to drive and drive it. The point is, there's a fixed amount of processor cycles needed from when the ISR fires until I drive the pins. After this, I can be a little more relaxed about anything else I need to do during the ISR, like update the pattern count or load a new frame (explained later).&lt;PRE&gt;#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;ISR( TIMER2_COMPA_vect ){&lt;br /&gt;  TCNT2 = 0; // Reset Timer2 counter to divide...&lt;br /&gt;&lt;br /&gt;  boolean bit_ = bitRead(dcc_bit_pattern_buffered[c_buf&amp;gt;&amp;gt;3], c_buf &amp; 7 );&lt;br /&gt;&lt;br /&gt;  if( bit_ ) {&lt;br /&gt;    DRIVE_1();&lt;br /&gt;  } else {&lt;br /&gt;    DRIVE_0();&lt;br /&gt;  }  &lt;br /&gt;  &lt;br /&gt;  /* Now update our position */&lt;br /&gt;  if(c_buf == dcc_bit_count_target_buffered){&lt;br /&gt;    c_buf = 0;&lt;br /&gt;    load_new_frame();&lt;br /&gt;  } else {&lt;br /&gt;    c_buf++;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;};&lt;/PRE&gt;&lt;H2&gt;Building Control Packets&lt;/H2&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_nw9n44o883o/TTefObfBl-I/AAAAAAAAABs/hJiFXmXixCA/s1600/dcc_driver_data_flow.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 184px;" src="http://4.bp.blogspot.com/_nw9n44o883o/TTefObfBl-I/AAAAAAAAABs/hJiFXmXixCA/s320/dcc_driver_data_flow.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5564090934884407266" /&gt;&lt;/a&gt; There are two steps to getting packet UI data ready for transmission. First, the UI pattern must be constructed using the latest address, speed and direction data that the firmware has received from the serial link. And then when the driver interrupt is ready for it, the packet is copied to a buffer area so that output data is never updated mid way through the transmission of a packet. The picture right gives the general idea.&lt;br /&gt;&lt;br /&gt;To keep things simple for the interrupt routine, I built a list of highs and lows that must be transmitted for a given packet. Now, each time the ISR fires it just outputs the next level in the list. For example, if I wanted to drive a packet of &lt;CODE&gt;1001&lt;/CODE&gt;, I'd actually be driving 12 UIs (&lt;CODE&gt;LO HI, LO LO HI HI, LO LO HI HI, LO HI&lt;/CODE&gt;) on the pins. So I set up an array of &lt;CODE&gt;byte&lt;/CODE&gt;s called &lt;CODE&gt;dcc_bit_pattern&lt;/CODE&gt; to hold this &lt;CODE&gt;HI LO HI ...&lt;/CODE&gt; sequence. It was sized so that it would hold the worst case packet length, transmitting all &lt;CODE&gt;0&lt;/CODE&gt;'s.&lt;br /&gt;&lt;br /&gt;So after receiving a new direction instruction, I'd determine the frame data and write it to this packet buffer in UI format. All the while, I'd be keeping a count of the number of UIs in the packet, and when I'd finished building the packet, squirrel this final UI count away for use later. To build a packet from the address, speed and direction data, I call &lt;CODE&gt;build_packet()&lt;/CODE&gt;, which in turn calls a general-purpose packet builder function called &lt;CODE&gt;_build_packet()&lt;/CODE&gt;, shown next:&lt;br /&gt;&lt;PRE&gt;void _build_frame( byte byte1, byte byte2, byte byte3) {&lt;br /&gt;   &lt;br /&gt;  // Build up the bit pattern for the DCC frame &lt;br /&gt;  c_bit = 0;&lt;br /&gt;  preamble_pattern();&lt;br /&gt;&lt;br /&gt;  bit_pattern(LOW);&lt;br /&gt;  byte_pattern(byte1); /* Address */&lt;br /&gt;&lt;br /&gt;  bit_pattern(LOW);&lt;br /&gt;  byte_pattern(byte2); /* Speed and direction */&lt;br /&gt;&lt;br /&gt;  bit_pattern(LOW);&lt;br /&gt;  byte_pattern(byte3); /* Checksum */&lt;br /&gt;&lt;br /&gt;  bit_pattern(HIGH);  &lt;br /&gt;  &lt;br /&gt;  dcc_bit_count_target = c_bit;&lt;br /&gt;  &lt;br /&gt;};&lt;/PRE&gt;&lt;br /&gt;The &lt;CODE&gt;byte_pattern()&lt;/CODE&gt; function takes a byte and converts it to a string of UIs. For example, given an address of &lt;CODE&gt;12&lt;/CODE&gt;, this is &lt;CODE&gt;b0000_1010&lt;/CODE&gt; in binary and the &lt;CODE&gt;byte_pattern()&lt;/CODE&gt; function would add the UIs &lt;CODE&gt;{LO LO HI HI, LO LO HI HI, LO LO HI HI, LO LO HI HI, LO HI, LO LO HI HI, LO HI, LO LO HI HI}&lt;/CODE&gt; to the current packet being constructed.&lt;br /&gt;&lt;br /&gt;The function &lt;CODE&gt;byte_pattern()&lt;/CODE&gt; uses &lt;CODE&gt;bit_pattern()&lt;/CODE&gt; which really does all the donkey work, doing the actual logic-to-UI conversion.  Starting at position held in variable &lt;CODE&gt;c_bit&lt;/CODE&gt;, &lt;CODE&gt;bit_pattern()&lt;/CODE&gt; will lay down &lt;CODE&gt;LO HI&lt;/CODE&gt; or &lt;CODE&gt;LO LO HI HI&lt;/CODE&gt; for each bit and will increment the UI counter &lt;CODE&gt;c_bit&lt;/CODE&gt; as it goes.&lt;br /&gt;&lt;PRE&gt;void bit_pattern(byte mybit){&lt;br /&gt;&lt;br /&gt;    bitClear(dcc_bit_pattern[c_bit&amp;gt;&amp;gt;3], c_bit &amp; 7 );&lt;br /&gt;    c_bit++;&lt;br /&gt;    &lt;br /&gt;    if( mybit == 0 ) {&lt;br /&gt;       bitClear(dcc_bit_pattern[c_bit&amp;gt;&amp;gt;3], c_bit &amp; 7 );&lt;br /&gt;       c_bit++;   &lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    bitSet(dcc_bit_pattern[c_bit&amp;gt;&amp;gt;3], c_bit &amp; 7 );&lt;br /&gt;    c_bit++;&lt;br /&gt;    &lt;br /&gt;    if( mybit == 0 ) {&lt;br /&gt;       bitSet(dcc_bit_pattern[c_bit&amp;gt;&amp;gt;3], c_bit &amp; 7 );&lt;br /&gt;       c_bit++;   &lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;}&lt;/PRE&gt;&lt;br /&gt;The position of a given UI in the packet's &lt;CODE&gt;byte&lt;/CODE&gt; array &lt;CODE&gt;dcc_bit_pattern&lt;/CODE&gt; is decoded from the UI counter. The three LSBs, &lt;CODE&gt;c_bit[2:0]&lt;/CODE&gt; are the position within the byte and the remaining MSBs are the &lt;CODE&gt;byte&lt;/CODE&gt; address. This explains the &lt;CODE&gt;bitClear(dcc_bit_pattern[c_bit&amp;gt;&amp;gt;3], c_bit &amp; 7 )&lt;/CODE&gt; stuff that's going on both here and in the ISR.&lt;br /&gt;&lt;br /&gt;When the packet is built and the driver interrupt is ready for it, the packet is copied to a buffer area so that a transmitted packet is never updated mid way through being updated. The function &lt;CODE&gt;load_new_packet()&lt;/CODE&gt; takes care of copying the new UI data and updating the buffered UI target count.&lt;br /&gt;&lt;H2&gt;Reading Control Strings via Serial I/O&lt;/H2&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_nw9n44o883o/TTefOu8v50I/AAAAAAAAAB0/ZBKnr2ixsY8/s1600/dcc_serial_fsm.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 320px;" src="http://3.bp.blogspot.com/_nw9n44o883o/TTefOu8v50I/AAAAAAAAAB0/ZBKnr2ixsY8/s320/dcc_serial_fsm.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5564090940109350722" /&gt;&lt;/a&gt;To read a control string from the serial port, I've used the &lt;CODE&gt;Serial&lt;/CODE&gt; module and a finite state machine (FSM). The FSM detects a string in the form: &lt;CODE&gt;"A" digit digit digit ":" "F" or "B" ":" "S" digit&lt;/CODE&gt;. If there's a handier way to do this, I'm all ears. The FSM diagram for this is shown below, with the red transitions being the main loop, and the dashed transistions being followed when there's an error. I snuck a few testmodes in there too: one so I could drive the rails constantly long enough to put a multimeter on them; and another to tweak the timer target count.&lt;br /&gt;&lt;br /&gt;Having the firware controlled by strings passed through the serial port opens up some interesting capabilities. For instance, I didn't know the address of the train initially, so I wrote small Python script to cycle through all the addresses and wait a while to see if the train responded (it turned out to be '1'):&lt;PRE&gt;#! /usr/bin/env python&lt;br /&gt;""" Try to find the address of dad's train... """&lt;br /&gt;&lt;br /&gt;from time import sleep&lt;br /&gt;&lt;br /&gt;import serial&lt;br /&gt;&lt;br /&gt;link = serial.Serial('/dev/ttyUSB0', baudrate=9600, timeout=2)&lt;br /&gt;&lt;br /&gt;def search_address():&lt;br /&gt;	for address in range(127):&lt;br /&gt;		print "Address %03d" % (address)&lt;br /&gt;		link.write("A%03d:F:S3" % address )&lt;br /&gt;		sleep(10)&lt;br /&gt;	&lt;br /&gt;if __name__ == '__main__':&lt;br /&gt;	search_address()&lt;/PRE&gt;&lt;br /&gt;&lt;br /&gt;I also wrote one to move the train back and forth along the track:&lt;PRE class="code"&gt;#! /usr/bin/env python&lt;br /&gt;from time import sleep&lt;br /&gt;import serial&lt;br /&gt;&lt;br /&gt;link = serial.Serial('/dev/ttyUSB0', baudrate=9600, timeout=2)&lt;br /&gt;print "Link:", link&lt;br /&gt;for i in xrange(10):&lt;br /&gt;    link.write("A001:F:S5")&lt;br /&gt;    sleep(10)&lt;br /&gt;    link.write("A001:B:S6")&lt;br /&gt;    sleep(14)&lt;/PRE&gt;&lt;br /&gt;&lt;H2&gt;The Grand Opening&lt;/H2&gt;So after all this, you might be interested in what my dad thought of the whole endeavour. I took it back home and showed him, and he was like "Meh, that's nice I suppose. I'm more interested in the wireless control that's about these days...". Fair play, no point in using old tech, I suppose!&lt;H2&gt;References&lt;/H2&gt;&lt;UL&gt;&lt;LI&gt;teh codez: &lt;A HREF="https://github.com/Harnesser/DCC-Controller"&gt;[github]&lt;/A&gt;&lt;/LI&gt;&lt;LI&gt;Arduino Port Mapping: &lt;A HREF="http://arduino.cc/en/Reference/Atmega168Hardware"&gt;[arduino.cc]&lt;/A&gt;&lt;/LI&gt;&lt;LI&gt;Port Manipulation: &lt;A HREF="http://arduino.cc/en/Reference/PortManipulation"&gt;[arduino.cc]&lt;/A&gt;&lt;/LI&gt;&lt;LI&gt;Benchmarking different ways of changing Arduino pins: &lt;A HREF="http://www.billporter.info/ready-set-oscillate-the-fastest-way-to-change-arduino-pins/"&gt;[billporter.info]&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7763117497297224225-4437698266838497873?l=amakersblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/4437698266838497873/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7763117497297224225&amp;postID=4437698266838497873' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/4437698266838497873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/4437698266838497873'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/2011/01/dcc-firmware-for-arduino.html' title='DCC Firmware for Arduino'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_nw9n44o883o/TTecEZqiOjI/AAAAAAAAABU/w03QumHDXL4/s72-c/dcc_signal.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763117497297224225.post-5824879805296333534</id><published>2011-01-15T11:24:00.000-08:00</published><updated>2011-01-15T11:43:07.790-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='l293d'/><category scheme='http://www.blogger.com/atom/ns#' term='arduino'/><category scheme='http://www.blogger.com/atom/ns#' term='dcc'/><title type='text'>Controlling Model Trains with an Arduino</title><content type='html'>&lt;H2&gt;‎Hear My Train a Coming&lt;/H2&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_nw9n44o883o/TTH07niKriI/AAAAAAAAAA8/19uc-XPAtFY/s1600/dcc_dads_train.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 178px;" src="http://4.bp.blogspot.com/_nw9n44o883o/TTH07niKriI/AAAAAAAAAA8/19uc-XPAtFY/s320/dcc_dads_train.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5562496319841021474" /&gt;&lt;/a&gt;I was back home a few months ago, and I was in the auld fella's shed. He was giving me the grand tour of the model railway setup he was building (OO guage, I believe). Dad's kinda more into the scenery, building buildings, and wiring the tracks rather than playing with the trains. But what interested me was the operation of the trains - he could have a couple of trains on the tracks and control them seperately, going at different speeds and directions. But there's only two wires! What kind of magic was this?&lt;br /&gt;&lt;br /&gt;Turns out it was Digital Command Control, or DCC.&lt;br /&gt;&lt;H2&gt;The Golden Age of Steam&lt;/H2&gt;Back in olden times, the motors onboard model trains got their power (either AC or DC) from the tracks that the train ran on. This was cool if you had only the one train, you could control its speed by varying the voltage on the tracks, and if you had a DC setup, its direction by flipping the polarity. But if you wanted to run two or more trains at the same time on the same tracks, they'd go at the same speed in the same direction. Not too realistic. Or fun, I can imagine.&lt;br /&gt;&lt;br /&gt;That's unless you split up the track layout into separate zones electrically. So a train on zone 1 say, would go at a different speed from a train on zone 2. This setup worked but was very flakey in a number of dimensions. It was especially troublesome at the boundaries between these sections, usually at the points. Points, if you don't know, are those things on a railway which direct a train onto one branch of a track or the other. In model railway land, with the tracks being electrically conductive and all, the points are essentially DPDT switches which can end up shorting the zones if things are not properly controlled. I'm a bit fuzzy on the details here to be honest, so I'll continue...&lt;H2&gt;DCC&lt;/H2&gt;Anyways, DCC is the solution to all this. It's quite cool. Instead of DC or a sinewave on the rails, you drive a digital control packet at roughly +-15V. The motor on the train takes its power from this DCC signal (rectifies it, I think), and a chip onboard each train decodes the control packet to set the direction and speed of the train. Since each DCC train can be programmed with an address, each train on a layout can be individually addressed and controlled all without tricky zone wiring! Brill! For a train that's not being addressed, it can still rectify the signals on the rails to power its motor. And if its not being addressed, the train keeps doing what it's doing.&lt;H2&gt;I had a spare Arduino&lt;/H2&gt;This was very interesting to me. Digital control, eh? I had a spare Arduino - I'd brought my RGB LED project to show the nephew/nieces. Digital Control. A spare Arduino. A plan was forming. Could I possibly program my Arduino to digitally control my dad's trains?&lt;H2&gt;Power&lt;/H2&gt;The first problem was electrical. The Arduino pumps out 5V, and the trains would require a swing of ideally ±15V and quite a bit of current. So I was thinking MOSFET H-Bridge switching a hefty power supply and controlled by the Arduino's outputs. But I had no MOSFETs to hand. Luckily, my dad had a few &lt;A HREF="http://www.datasheetcatalog.com/datasheets_pdf/L/2/9/3/L293D.shtml"&gt;L293D&lt;/A&gt;'s lying about (he's cool like that). So with a bit of stripboard and a chopped up DIL socket I had a quick and dirty power driver circuit ready to go. A dusty wall wart rated for 12V DC (giving me ±6V) sourced from the bottom drawer in my dad's shed would supply the necessary power. The general idea of the circuit is shown below:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_nw9n44o883o/TTH1uo-Rr0I/AAAAAAAAABE/SG6szKNPKAE/s1600/dcc_driver_circuit.png"&gt;&lt;img style="display:block; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 218px;" src="http://3.bp.blogspot.com/_nw9n44o883o/TTH1uo-Rr0I/AAAAAAAAABE/SG6szKNPKAE/s320/dcc_driver_circuit.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562497196400684866" /&gt;&lt;/a&gt;&lt;br /&gt;I used two of the four H-Bridge legs in the L293D to steer the 12V across the tracks. By controlling inputs 1A and 2A carefully, I could put +12V on one rail and 0V on the other, and vice versa, giving a swing of ±6V. This is not exactly to spec, but seemed to work for two trains at least.&lt;br /&gt;&lt;H2&gt;The Grand Plan&lt;/H2&gt;Now that I was happy with the physics, it was time to get metaphysical. The basic DCC spec defines a packet made up of the train address, its direction and its speed. So I thought it would be nice if I could send an address:direction:speed triplet from a computer GUI to the Arduino via the USB/serial port. My firmware on the Arduino would then convert this command triplet string into voltage waveforms on its output pins, that would drive the power H-Bridge made from the L293D to, in turn, control the train.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_nw9n44o883o/TTH2nWKyk_I/AAAAAAAAABM/YzQ4b3CKMq8/s1600/dcc_system_setup.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 210px;" src="http://3.bp.blogspot.com/_nw9n44o883o/TTH2nWKyk_I/AAAAAAAAABM/YzQ4b3CKMq8/s400/dcc_system_setup.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562498170605442034" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So that's what I did. Although I didn't get it completed at home, so the auld fella tacked a few sections of track onto a length of 2x1 and let me borrow a train.&lt;H2&gt;Firmware&lt;/H2&gt;So when I got back to base, I started on the firmware. The firmware to implement the basic DCC spec is interesting enough and would make an interesting post on its own. So that's what I'll do.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7763117497297224225-5824879805296333534?l=amakersblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/5824879805296333534/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7763117497297224225&amp;postID=5824879805296333534' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/5824879805296333534'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/5824879805296333534'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/2011/01/controlling-model-trains-with-arduino.html' title='Controlling Model Trains with an Arduino'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_nw9n44o883o/TTH07niKriI/AAAAAAAAAA8/19uc-XPAtFY/s72-c/dcc_dads_train.jpg' height='72' width='72'/><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763117497297224225.post-7010497391450901915</id><published>2010-06-15T14:58:00.000-07:00</published><updated>2010-06-15T15:06:06.289-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='systemverilog'/><category scheme='http://www.blogger.com/atom/ns#' term='verilog'/><title type='text'>SystemVerilog is a Big Mistake</title><content type='html'>I think we dropped the ball with SystemVerilog.&lt;br /&gt;* It's based on old tech (but at least it has garbage collection). Why is it not more Python-like, y'know easier.&lt;br /&gt;* It's a mishmash of languages&lt;br /&gt;* It's getting 'unattainable'. For example, if you want to plug away at it on your own, there's no free simulator that you can practice with.  &lt;br /&gt;&lt;H2&gt;Toward a Fully Featured Programming Language&lt;/H2&gt;&lt;br /&gt;The Verilog standard should've only been updated to make it more useful from a HARDWARE DESCRIPTION point of view. SystemVerilog is an effort to grow Verilog towards a more traditional OOP programming language - and that's what's back to front. We should've taken Python (&lt;tt&gt;yield&lt;/tt&gt;) (or even Go - after all it's built around concurrency and it compiles PDQ (not TCL, please)) and grown it to include a Verilog DUT.&lt;br /&gt;SV adds useful stuff like hashes and &lt;tt&gt;foreach&lt;/tt&gt; loops that make it a lot more expressive - stuff that's empiricaly proven to increase productivity by 100.09%. But why not just start from a real programming language in that case? It's not like OOP testbenches do connectivity and timing like traditional RTL - SV testbenches expect you to call &lt;tt&gt;.run()&lt;/tt&gt; on all your class instantiations and pass around handles to interfaces for connectivity. And since we're back to forking a load of &lt;tt&gt;.run()&lt;/tt&gt; methods, why not start from a 'real' programming language, and allow it to twiddle the inputs of RTL descriptions of hardware?&lt;br /&gt;&lt;H2&gt;Adding Broken Things&lt;/H2&gt;&lt;br /&gt;Since SV is a huge amalgamation of things by an amalgamation of vested interests, things were added to the SV standard that should not have been.&lt;br /&gt;&lt;H3&gt;&lt;tt&gt;program&lt;/tt&gt; Block Fail&lt;/H3&gt;&lt;br /&gt;Also, what's with the &lt;tt&gt;program&lt;/tt&gt; blocks?  That's a fail right there.  And we still have problems with time -0 initialisation, still have possible race conditions at the start of a sim if you want a monitor module to have reasonable defaults, and then change them at the start of an initial block.&lt;br /&gt;&lt;H3&gt;&lt;tt&gt;final&lt;/tt&gt; Blocks&lt;/H3&gt;&lt;br /&gt;I don't get these.  They're supposed to be able to let you do things at the end of the simulation. But like most Verilog procedural blocks, you've no visibility on the order that they'll execute. So say you want to open a file at the end of a simulation and have all your testbench monitors write their status to it. Yay, so put a &lt;tt&gt;final&lt;/tt&gt; block in each of your monitor blocks to write to the file... uh, hold on, how do you know that file has been opened? How do you keep the order consistent? Ah, I know, call a &lt;tt&gt;.summary()&lt;/tt&gt; function/method for each of your monitors. But now to call these functions you need to know what monitors you have, so monitors have to register themselves somewhere because SV has no introspection. So now you've a single &lt;tt&gt;final&lt;/tt&gt; block calling a bunch of &lt;tt&gt;.summary()&lt;/tt&gt; functions and if you've only one &lt;tt&gt;final&lt;/tt&gt; block, what's the point? You may as well just have a function that you call at the end of your '&lt;tt&gt;main()&lt;/tt&gt;' &lt;tt&gt;initial&lt;/tt&gt; procedure.&lt;br /&gt;&lt;H2&gt;Open Verification? Hmmm...&lt;/H2&gt;&lt;br /&gt;SV testbench-building methodologies seem to be settling around the UVM - a nice 'open' standard that's being put together by the Accellera consortium. Yeah, you can download the code for free and have a peek at it, and maybe send some patches back to fix things that trouble you, but it ain't open, baby. If you have to pay loads of cash for a simulator to run this, I'm not sure that you can claim that it's open.&lt;br /&gt;This is another good reason for going the &lt;tt&gt;{Real_Programming_Language, Verilog}&lt;/tt&gt; route. With just a Verilog-2001 open source simulator, open source programming language and some tasty interfacing, you'd be able to run fancy testbenches on pre-existing RTL from the comfort of your own home. No expensive licenses needed. And more than that, you wouldn't have to limit the maximum concurrent jobs on the compute farm to 10 when doing regressions because co-workers write pleading e-mails to you not to hog the licenses...&lt;br /&gt;&lt;H2&gt;Assertions, Coverage &amp; Constrained Randomisation&lt;/H2&gt;&lt;br /&gt;I admit that I haven't used assertions, coverpoints or constrained randomisation in anger. And I suspect that this weakens my argument somewhat. But this could be done in a Python module instead of, y'know, bolting together several existing languages? I've a feeling I underestimate the amount of work needed to get all this stuff working. Yip, I admit it - this portion of my argument is weak.&lt;br /&gt;&lt;H2&gt;Companies&lt;/H2&gt;&lt;br /&gt;Companies. Why would they do &lt;tt&gt;{Real_Programming_Language, Verilog}&lt;/tt&gt; when they could build SystemVerilog to steer us away from the opensource verilog simulators that were somewhat catching up, and make us all move to something that we need to look on feature vs price matrices to see which portions of the bright new thing we can afford to run? Companies, I suppose I can have nothing against them, after all I do work for one! They have to make a buck, I suppose. &lt;br /&gt;&lt;H2&gt;So...&lt;/H2&gt;&lt;br /&gt;It's interesting to think about what a "Real Programming Language + Verilog 2001" SystemVerilog would look like. What Real Programming Language would we use? Would it actually improve productivity?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7763117497297224225-7010497391450901915?l=amakersblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/7010497391450901915/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7763117497297224225&amp;postID=7010497391450901915' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/7010497391450901915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/7010497391450901915'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/2010/06/systemverilog-is-big-mistake.html' title='SystemVerilog is a Big Mistake'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763117497297224225.post-2457037789145280024</id><published>2010-03-09T16:14:00.000-08:00</published><updated>2010-03-09T17:17:28.846-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='information management'/><title type='text'>That Wiki Thing...</title><content type='html'>It's been roughly a year since my pet wiki has been active on the company's intranet.  It's definitely been useful, but I think it hasn't completely lived up to the hopes and dreams I had for it.&lt;br /&gt;&lt;H3&gt;Usefulness to My Good Self&lt;/H3&gt;As I'd planned, I've been using it as a kinda design notebook, although I still scribble on real paper as it's the quickest way to record thoughts.  When I write a wiki page, I find I write for an audience other than myself.  And that's no bad thing as I have to state assumptions and 'formally' defend any assertions.  I'm convinced this is ok; my paper notebook is for exploration and the wiki is the crystalisation of the thought process that lead to the final design.  The wiki is the definitive source of information about a topic, not a discussion.  The wiki has added a sense of rigor to thinking behind the stuff I produce. &lt;br /&gt;&lt;br /&gt;Y'know, maybe I shouldn't be setting up wiki pages willy-nilly.  I shouldn't actually be doing my design in wiki pages.  Wiki pages are supposed to be solid information, not cloudy half-thought-out explorations.  It should not really be an extension of my paper notebook, should it?&lt;br /&gt;&lt;H3&gt;Usefulness to My Teammates&lt;/H3&gt;This is harder to judge.  I think it's somewhat useful to my teammates in a read-only sense, but that it's still considered as "Marty's wiki" and not "the wiki" as I'd hoped.&lt;br /&gt;I have made an effort to let people know of its existence. After I complete a body of work, I check that the page in the wiki is reasonably accurate and then the link is sent around in the 'announcement' email.  For example: &lt;BLOCKQUOTE&gt;Hi All, I'm finished setting up the co-sim environment for our latest chip (which is the bee's knees, BTW, and going to make our company millions). See here (http://ourgroupswiki.some.address.com/)  for info on the environment and instructions for launching a sim&lt;/BLOCKQUOTE&gt;That sort of thing.  And there is evidence that people read it, but they don't edit it if something's amiss.  I do get the odd query on the accuracy of instructions, but my teammates never change the information themselves.  Maybe they've better things to be doing - maybe they don't feel that they're an expert in that field so need consensus. Who knows?&lt;br /&gt;&lt;H3&gt;The Elephant in the Room - Sharepoint&lt;/H3&gt;The wiki's relationship with Sharepoint is still mostly undefined.&lt;br /&gt;&lt;br /&gt;Sharepoint is our company's blessed online collaboration thingy.  But it's become a dumping ground for powerpoints and word documents.  And mostly Office 2007 versions of stuff I've no hope of opening on my linux workstation (vendor lock-in, much?).  Rant aside, this is where the latest datasheets, latest marketing info, latest formal design documents go.  And to be honest, it's probably the correct place for that info.&lt;br /&gt;&lt;H3&gt;So...&lt;/H3&gt;I need to properly define the wiki's place in the grand scheme of things. I know it has one, but I haven't yet been able to articulate it.  I also need to ask my teammates why it's not "the wiki" yet.&lt;br /&gt;&lt;br /&gt;I dunno why I'm invested in this so much.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7763117497297224225-2457037789145280024?l=amakersblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/2457037789145280024/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7763117497297224225&amp;postID=2457037789145280024' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/2457037789145280024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/2457037789145280024'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/2010/03/that-wiki-thing.html' title='That Wiki Thing...'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763117497297224225.post-6318900921746899850</id><published>2010-02-09T17:20:00.000-08:00</published><updated>2010-02-09T17:32:41.429-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='csd'/><title type='text'>Canonical Signed Digit Representation</title><content type='html'>I've recently had the opportunity to play around with multiplierless filter designs. Here's some Python code to convert numbers to and from Canonical Signed Digit (CSD) representation.  It does fractional too, as I like to keep track of my binary points with negative net indices in Verilog-land.&lt;br /&gt;&lt;br /&gt;It's based on a short paper I can't remember the name of.  More specifically, it's based on the pictures from a short paper I can't remember the name of as I couldn't really follow all the set theory in the text.&lt;br /&gt;&lt;br /&gt;To use it, put it on your path somewhere and:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;canavan% python &lt;br /&gt;Python 2.6.4 (r264:75706, Dec  7 2009, 18:45:15) &lt;br /&gt;[GCC 4.4.1] on linux2&lt;br /&gt;Type "help", "copyright", "credits" or "license" for more information.&lt;br /&gt;&gt;&gt;&gt; import csd&lt;br /&gt;&gt;&gt;&gt; csd.to_csd(34)&lt;br /&gt;'+000+0'&lt;br /&gt;&gt;&gt;&gt; csd.to_csd(34.75)&lt;br /&gt;'+00+0-'&lt;br /&gt;&gt;&gt;&gt; csd.to_csd(34.75,4)&lt;br /&gt;'+00+0-.0-00'&lt;br /&gt;&gt;&gt;&gt; csd.to_csd(34.75,6)&lt;br /&gt;'+00+0-.0-0000'&lt;br /&gt;&gt;&gt;&gt; csd.to_decimal('+0000')&lt;br /&gt;16.0&lt;br /&gt;&gt;&gt;&gt; csd.to_decimal('+0000.0-000+0-000+0000-')&lt;br /&gt;15.761955261230469&lt;br /&gt;&gt;&gt;&gt; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Beware, I don't do any input validation yet...&lt;br /&gt;&lt;br /&gt;Oh yeah, linkage: http://sourceforge.net/projects/pycsd/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7763117497297224225-6318900921746899850?l=amakersblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/6318900921746899850/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7763117497297224225&amp;postID=6318900921746899850' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/6318900921746899850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/6318900921746899850'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/2010/02/canonical-signed-digit-representation.html' title='Canonical Signed Digit Representation'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763117497297224225.post-5489681121641841334</id><published>2009-07-16T15:58:00.000-07:00</published><updated>2009-07-16T16:08:51.994-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='asic verification'/><category scheme='http://www.blogger.com/atom/ns#' term='asic design'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>I Program Computers</title><content type='html'>A new housemate moved in recently.  We were getting to know each other - talking about our backgrounds, our favourite football teams and all the usual getting-to-know-you good stuff. He'd half remembered from our initial meeting that I did something vaguely technical for a living, and asked did I "program computers or what?".&lt;br /&gt;"I'm an electronics engineer.  I help to design the digital parts of chips", I NACKed.&lt;br /&gt;"Ah", says he, "so how do you do that then?"&lt;br /&gt;"Emm", I was caught out. "By ah, programming computers...", I sheepishly admitted.&lt;br /&gt;It brings up a topic close to my heart - are Electronic Engineers (EEs) learning as much as they should from Computer Science and Software Engineering?&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Digital Design is Programming&lt;/h3&gt;&lt;br /&gt; Software Engineering is important to EEs because digital designers, and especially functional verification engineers, are in essence specialised software engineers.  For digital designers, our thoughts are necessarily grounded in hardware but those thoughts are expressed in software.  The special requirements of concurrency and timing for describing hardware requires dedicated Hardware Description Languages (HDLs), but these are programming languages none the less - computers can be made to execute them.&lt;br /&gt;&lt;br /&gt; If computers can run our HDLs as programs, then its natural as engineers to want to check the arse off our designs before they make it to manufacturing.  We want to make sure that we've expressed our ideas correctly.  We're obsessive about checking so we put our functional verification engineer hats on and we run simulations, and now we're suddenly programming for real.  Our testbenches and testcases are now software proper.  It no longer matters if the code we write is translatable into flip-flops and NOR gates, so long as the input signals are wiggled in the correct way and that the outputs wiggle as we'd expect.  And even better (maybe?), we're allowed to abstract now.&lt;br /&gt;&lt;br /&gt; I'm of the opinion that a lot of Electronic Engineers don't read enough about software development as they should.  Software seems to be, or at least seemed to be, a minor detail that we could get the co-op to sort out. And as far as my own university course was concerned - why did I have to independently discover the joys of source control?  I've read a few books like "Code Complete", "Emergent Design" and "Pragmatic Programmer" and wished with every line I read that an equivalent existed for us digital designers.  Maybe there is, it's just that programming related resources are easier to find on the web.&lt;br /&gt;&lt;br /&gt; Since we're all programmers now, we should learn how to program.  From what I read, real software programmers seem to have a small niggling worry that they're somehow inferior to 'real' engineers.  That's backwards though - us 'real' engineers need to start befriending real programmers and learn from them.  We're so dependent on computers that we need to learn how to program for real.  We need source control, we need unit tests, we need to learn to refactor and we need to learn to spot code smells.  We need to write scripts to generate RTL, scripts to launch batches of sims over the network and create Makefiles to automate synthesis. We're software engineers and we haven't the &lt;i&gt;slightest&lt;/i&gt; clue we are - at least, we've no ideal we will be when we leave college.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7763117497297224225-5489681121641841334?l=amakersblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/5489681121641841334/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7763117497297224225&amp;postID=5489681121641841334' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/5489681121641841334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/5489681121641841334'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/2009/07/i-program-computers.html' title='I Program Computers'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763117497297224225.post-6256094923147619198</id><published>2009-05-04T18:36:00.000-07:00</published><updated>2009-05-04T19:09:02.820-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RTL Visualiser'/><title type='text'>Drawing Circuit Diagrams - Update</title><content type='html'>Well, after a bit of wrangling with the EGB layout algorithm - things are working out!&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_nw9n44o883o/Sf-Zhej5gfI/AAAAAAAAAAo/1gX8kXH5o8o/s1600-h/spider_2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 107px;" src="http://4.bp.blogspot.com/_nw9n44o883o/Sf-Zhej5gfI/AAAAAAAAAAo/1gX8kXH5o8o/s320/spider_2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5332149284248322546" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There are still a few crossovers on the outputs of U8 &amp; U9 which I haven't got to the bottom of yet...&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Animation&lt;/h3&gt;&lt;br /&gt;To help get to the bottom of such things, I've implemented a bit of animation to show me how the layout is progressing at each step. Using python's &lt;code&gt;generator&lt;/code&gt;s to unroll the main layout loop was the key here.  First, the circuit data structure is drawn, then after a small delay the &lt;code&gt;.next()&lt;/code&gt; is called on the generator, and the circuit redrawn.  This continues until the generator is spent. Pretty nifty if I do say so myself...&lt;br /&gt;&lt;br /&gt;&lt;H3&gt;Improvements&lt;/H3&gt;&lt;br /&gt;At the minute, the layout algorithm is sweeping from the inputs of the circuit to the outputs.  I'm worried that this won't be optimum for untangling all types of circuits. So, once I debug my EGB algorithm implementation, I'll experiment with the following to see what gives the best results:&lt;br /&gt;&lt;UL&gt;&lt;br /&gt;&lt;LI&gt;inputs to outputs&lt;/LI&gt;&lt;br /&gt;&lt;LI&gt;outputs to inputs&lt;/LI&gt;&lt;br /&gt;&lt;LI&gt;inputs to outputs to inputs&lt;/LI&gt;&lt;br /&gt;&lt;/UL&gt;&lt;br /&gt;I'm also concerned about the initial state of the circuit data structures.  Maybe I've giving the algorithm too easy of a time. The instantiations in the circuit data structure are more or less in the order that they are in the verilog file.  Maybe I should mix-up the instantiation order in the verilog files.  Or maybe have a switch to randomize the instantiation orders in the data structure...&lt;br /&gt;&lt;br /&gt;I've also to trawl/profile the code and look for optimizations...&lt;br /&gt;&lt;br /&gt;&lt;H3&gt;Next Steps&lt;/H3&gt;&lt;br /&gt;After playing around with the layout algorithm, I think I'll add a final stage to tidy up the drawing of the nets.  Once I get something half-pretty going, I'll concentrate on parsing a bigger subset of the verilog language.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7763117497297224225-6256094923147619198?l=amakersblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/6256094923147619198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7763117497297224225&amp;postID=6256094923147619198' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/6256094923147619198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/6256094923147619198'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/2009/05/drawing-circuit-diagrams-update.html' title='Drawing Circuit Diagrams - Update'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_nw9n44o883o/Sf-Zhej5gfI/AAAAAAAAAAo/1gX8kXH5o8o/s72-c/spider_2.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763117497297224225.post-1268806579042536110</id><published>2009-01-13T13:36:00.000-08:00</published><updated>2009-01-15T21:03:35.248-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='information management'/><title type='text'>Wikis</title><content type='html'>&lt;h1 class="black_stars_and_red_circles_on_notebook"&gt;Keeping Engineering Info in Wikis&lt;/h1&gt;&lt;br /&gt;I'm starting an experiment at work. I want to liberate the design notebook. And this revolution will be wikified.&lt;br /&gt;&lt;br /&gt;If my group 'published' sections of their notebooks on an intranet wiki, I'm convinced we'd see lots of benefits.  I realise that having a paper trail is very important for patents and such, but I don't envisage the wiki replacing the notebooks - rather that the entries in the wiki would be a somewhat more polished version of the more interesting and useful scribbles.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;What goes in the wiki?&lt;/h2&gt;Lots of things.  Solutions to weird bugs.  Testbench documentation.  I'd even suggest that an entry for &lt;i&gt;every major new block&lt;/i&gt; in each project goes into the wiki, with the important legacy stuff added as we go along. The block info would detail how the block works and more interestingly, why the block is.  More info than in an email introducing the block, but maybe less info than for a design review.  Even technical questions in emails to you could serve as topic pointers for a wiki page.&lt;br /&gt;&lt;br /&gt;I think it's the wrong place for sim results.  It's wrong for block pin lists or schematics.  It's probably the wrong place for anything which has to be copied from other sources to keep it up to date.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Benefits of Wikization&lt;/h2&gt;The obvious benefit is that all this stuff which normally lives in only one or two people's heads or inboxes is available to and searchable by the entire group.  Another benefit is that writing an entry in the wiki should focus the designer, making them think more about what they're doing which should help increase the quality of our designs.  It would also be a ready-made source for info and text for design review documents, datasheets, customer presentations and the like.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Resistance&lt;/h2&gt;There are a few drawbacks, though.  The main one is getting buy-in form the rest of the team.  I'm not naive - I know that if I tried to get it decreed that everyone has to use the wiki in the way I outline, it would raise eyebrows, roll eyes and be dismissed as another layer of red tape and beaureaucy.&lt;br /&gt;&lt;br /&gt;I have a plan* though - I'm going to lead by example and people will see the revolution as righteous.  I've started to put interesting stuff in the wiki and I'm starting to point team members to it when they come looking for info.  They're eventually going to start thinking, "Hmm, Marty would know that, I check that wiki thing of his before I ask him".  This is going to be cool for a while until they spot an error, at which time I'm going to lightly suggest that they get themselves an account and fix it up.  They're going to see the benefits of the wiki and start adding information themselves and things will get cooler.  OK, there was a leap of faith there, but there's no harm in trying it out.&lt;br /&gt;&lt;br /&gt;Aside: We've also a Sharepoint site too, but this seems to be a place for dumping documents and todo lists.  I'm going to have to think a bit more about how the wiki fits with it.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Initial Wiki Usage Observations&lt;/h2&gt;So.  The wiki I'm using at the moment is Wikimedia, because that's what sysadmin kindly set up for me. I like the way it stores edit history.  I am finding it useful.&lt;br /&gt;&lt;br /&gt;The main problem I see is with engineering diagrams.  There's no stable drawing plugin for that species of wiki. State diagrams and example timing diagrams have to be created elsewhere and uploaded as .pngs or whatever to the wiki.  I don't like the fact that the master document for the diagrams is elsewhere, making it difficult for others to correct or append them.  And even if there were a stable drawing plugin, would the drawings be of high enough quality to use in more formal documents?&lt;br /&gt;&lt;br /&gt;I think diagrams are important in engineering documentation, and would love if the barrier for entering diagrams into the wiki was lowered. I'd love if we all had graphics tablets (or tablet PCs) and could just scribble a quick diagram only for it to appear in the wiki.  I'm contradicting myself here a little, but if it's a tossup between no diagrams because its a pain in the arse to get them in the wiki and sketchy diagrams that need to be redrawn with more care for more formal documents, then sketchy wins for me all the time. I like diagrams...&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Future&lt;/h2&gt;I think the future of our group has a wiki in it.  Lets see how the experiment goes...&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Resources&lt;/h2&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;twiki&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;wikimedia&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;P&gt;* OK, it's not really my plan, I robbed it from http://www.randsinrepose.com/ , or more specifically, his book "Managing Humans"&lt;/P&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7763117497297224225-1268806579042536110?l=amakersblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/1268806579042536110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7763117497297224225&amp;postID=1268806579042536110' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/1268806579042536110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/1268806579042536110'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/2009/01/wikis.html' title='Wikis'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763117497297224225.post-438142638442795195</id><published>2008-10-16T08:33:00.000-07:00</published><updated>2010-01-14T13:43:07.683-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='verilog'/><title type='text'>Verilog RTL Decommenter</title><content type='html'>We're transferring a bit of soft IP to a customer, and decided to remove all the comments from the RTL files.  Our IP is protected by an NDA, so we decided against obfuscation as we felt this may cause unnecessary hassle if we're asked to help debug the IP integration.  We did decide to remove comments so that any stray profanity, "FIXME"s and "This is an ugly, ugly hack but..."s are not presented to the customer.  It was also an opportunity to include a copyright header to the RTL file, too.&lt;br /&gt;&lt;br /&gt;It fell to me to script the removal of the comments.  Being a bit of a python fan, I went searching for some pythonic regexp-based comment remover.  I found a C decommenter &lt;a href="http://www.saltycrane.com/blog/2007/11/remove-c-comments-python/"&gt;here&lt;/a&gt;, but it needed a few modifications to work with verilog comments which I present below.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;#! /usr/bin/env python&lt;br /&gt;&lt;br /&gt;# remove_comments.py&lt;br /&gt;import re&lt;br /&gt;&lt;br /&gt;def remove_comments(text):&lt;br /&gt;  """ remove c-style comments.&lt;br /&gt;      text: blob of text with comments (can include newlines)&lt;br /&gt;      returns: text with comments removed&lt;br /&gt;  """&lt;br /&gt;&lt;br /&gt;  pattern = r"""&lt;br /&gt;                          ##  --------- COMMENT ---------&lt;br /&gt;         /\*              ##  Start of /* ... */ comment&lt;br /&gt;         [^*]*\*+         ##  Non-* followed by 1-or-more *'s&lt;br /&gt;         (                ##  &lt;span style="color: rgb(51, 102, 255); font-weight: bold;"&gt;group 1&lt;/span&gt;&lt;br /&gt;           [^/*][^*]*\*+  ##&lt;br /&gt;         )*               ##  0-or-more things which don't start with /&lt;br /&gt;                          ##    but do end with '*'&lt;br /&gt;         /                ##  End of /* ... */ comment&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0); font-weight: bold;"&gt;         |                ##  -OR-&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0); font-weight: bold;"&gt;         //[^\n]*         ##  // comment to end of line&lt;/span&gt;&lt;br /&gt;       |                  ##  -OR-  various things which aren't comments:&lt;br /&gt;         (                ##  &lt;span style="color: rgb(51, 102, 255); font-weight: bold;"&gt;group 2&lt;/span&gt;&lt;br /&gt;                          ##  ------ " ... " STRING ------&lt;br /&gt;           "              ##  Start of " ... " string&lt;br /&gt;           (              ##&lt;br /&gt;             \\.          ##  Escaped char&lt;br /&gt;           |              ##  -OR-&lt;br /&gt;             [^"\\]       ##  Non "\ characters&lt;br /&gt;           )*             ##&lt;br /&gt;           "              ##  End of " ... " string&lt;br /&gt;         |                ##  -OR-&lt;br /&gt;                          ##&lt;br /&gt;                          ##  ------ ANYTHING ELSE -------&lt;br /&gt;           .              ##  Anything other char&lt;br /&gt;           [^/"'\\]*      ##  Chars which doesn't start a comment, string&lt;br /&gt;         )                ##    or escape&lt;br /&gt;"""&lt;br /&gt;&lt;br /&gt;  regex = re.compile(pattern, re.VERBOSE|re.MULTILINE|re.DOTALL)&lt;br /&gt;  noncomments = [m.group(2) for m in regex.finditer(text) if m.group(2)]&lt;br /&gt;&lt;br /&gt;  return "".join(noncomments)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;copyright = """//  --------------------------------------------------------------&lt;br /&gt;//&lt;br /&gt;//  My Company Inc.  - Confidential Information&lt;br /&gt;//  Copyright 2005-2008&lt;br /&gt;//&lt;br /&gt;//  --------------------------------------------------------------"""&lt;br /&gt;&lt;br /&gt;if __name__ == '__main__':&lt;br /&gt;  import sys&lt;br /&gt;  filename = sys.argv[1]&lt;br /&gt;  code_w_comments = open(filename).read()&lt;br /&gt;  code_wo_comments = remove_comments(code_w_comments)&lt;br /&gt;&lt;br /&gt;  #fh = open(filename+".nocomments", "w")&lt;br /&gt;  #fh.write(code_wo_comments)&lt;br /&gt;  #fh.close()&lt;br /&gt;&lt;br /&gt;  print copyright&lt;br /&gt;  print code_wo_comments&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;First of all, I added a bit to the regexp to spot one-line comments that start with &lt;code&gt;//&lt;/code&gt; - as mentioned in the &lt;a href="http://perldoc.perl.org/perlfaq6.html#How-do-I-use-a-regular-expression-to-strip-C-style-comments-from-a-file"&gt;perl FAQ&lt;/a&gt; - see the emphasised section in the above code.&lt;br /&gt;&lt;br /&gt;I also got rid of the single quote string matching section of the regexp because verilog doesn't have such strings.  It was also accidentally matching the code between two number specifiers which prevented the removal of the comments in what it thought was a string. For example, the comment below would not be removed:&lt;br /&gt;&lt;pre&gt;assign a = 1'b0;&lt;br /&gt;// Some comment&lt;br /&gt;assign b = 1'b1;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The regexp itself saves two groups; group 1 is comment group and group 2 is a non-comment group.  Printing group 2 is the thing to do if you want the comments removed.  If the regexp matches a comment, then group 1 is text and group 2 is empty - printing group 2 effectively "removes" the comment.  If the regexp matches a non-comment, then group 2 is text we want to keep, so we print it.&lt;br /&gt;&lt;br /&gt;This decommenter script is used as part of an overall script which prepares our code for handover.  The RTL is &lt;code&gt;exported&lt;/code&gt; from our CVS directory, decommented and &lt;code&gt;tar.gz&lt;/code&gt;'d - ready for secure FTPing to our customer...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7763117497297224225-438142638442795195?l=amakersblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/438142638442795195/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7763117497297224225&amp;postID=438142638442795195' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/438142638442795195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/438142638442795195'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/2008/10/verilog-rtl-decommenter.html' title='Verilog RTL Decommenter'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763117497297224225.post-1635520865087983523</id><published>2008-07-11T10:57:00.000-07:00</published><updated>2010-01-14T13:57:56.584-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='asic design'/><category scheme='http://www.blogger.com/atom/ns#' term='hassle'/><category scheme='http://www.blogger.com/atom/ns#' term='verilog'/><title type='text'>Fixed-Point Arithmetic with Verilog</title><content type='html'>I'm doing a bit of hardware RTL at the minute, which is a change from my usual testbench code.  I'm trying to implement a datapath using fixed-point arithmetic and I'm finding that verilog is not helping me as much as I thought it would. And I've come to realise something...&lt;br /&gt;&lt;br /&gt;Fixed-point arithmetic in verilog is broken.  And that makes me sad.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Representation&lt;/h2&gt;First things first.  Let's try to represent a fixed-point number in verilog.  What about a vector of bits? Cool, let's say we'll represent our fixed point numbers in N bits:&lt;br /&gt;&lt;h2&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_nw9n44o883o/SId8NCyGh4I/AAAAAAAAAAU/etVoBi27Vrc/s1600-h/fractional.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_nw9n44o883o/SId8NCyGh4I/AAAAAAAAAAU/etVoBi27Vrc/s320/fractional.JPG" alt="" id="BLOGGER_PHOTO_ID_5226282456113907586" border="0" /&gt;&lt;/a&gt;&lt;/h2&gt;We'll allow M bits for the integer part and F for the fractional (and, of course, M+F = N).&lt;br /&gt;&lt;pre&gt;reg [M+F-1:0] my_number;&lt;/pre&gt;OK, so far so good. This is not too self-documenting though - how can you tell that this is a fixed-point number? And where is its binary point? Even worse, you can't tell verilog that the number is supposed to be fixed-point - it doesn't even have a fixed-point 'type'.&lt;br /&gt;&lt;br /&gt;Another way is to signal a fixed-point number by having the fractional bits have negative indexes:&lt;br /&gt;&lt;div class="mycode"&gt;reg [M-1:-F] my_number;&lt;/div&gt;For example, an M=1 and F=4 number's vector would be indexed [0:-4]. In this case, we can decree that the binary point is always between indexes 0 and -1, and that any vectors declared with negative indices is a floating point number.  This also has the nice property that the value of each bit in the vector is 2&lt;sup&gt;index&lt;/sup&gt;, just like the integer representation.&lt;br /&gt;&lt;br /&gt;It's just bookkeeping, though.  Nomatter how we spin it, we can't really get verilog to help us out with our fixed-point numbers.  For example, say we wanted to add a 1.4 number to a 2.5 - (we'd expect a 3.5 result...):&lt;br /&gt;&lt;pre&gt;reg [0:-4] a;&lt;br /&gt;reg [1:-5] b;&lt;br /&gt;reg [3:-5] c;&lt;br /&gt;&lt;br /&gt;always @(*) begin&lt;br /&gt;//  c = &lt;span style="font-weight: bold;"&gt;a + b&lt;/span&gt;; // this won't line up the binary points for us&lt;br /&gt;    c = {a, 1'b0} + b; // we have to make sure that the binary points line up ourselves&lt;br /&gt;end&lt;/pre&gt;&lt;br /&gt;In this case, Verilog won't line up the binary points for us, it'll line the vectors up LSB to LSB.  We're left to make sure that we pad whichever vector to line up the binary points.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Display&lt;/h2&gt;Since we can't tell verilog we're working with fixed-point numbers, they're not going to be displayed correctly.  Any $displays in the testbench are going to display integers.  "But wait!", I hear you say - sure couldn't you just write a function to properly display your fixed-point numbers?  Not easily.  Functions can't be parameterised (as fair as I'm aware), so you'll have to write conversion functions for each different size of fixed-point number to be displayed.  The reason is because slices of vectors must have constant expressions: you can write&lt;code&gt;my_number[-1:F]&lt;/code&gt; if F is a parameter, but not if F is a variable.&lt;br /&gt;&lt;br /&gt;In a waveform viewer, our fixed-point numbers are going to be displayed as integers as well.  Unless we write expressions (in SimVision, anyway) to convert them.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;So, What Now?&lt;/h2&gt;To recap, you can't easily work with fixed-point numbers in verilog. Verilog can't help with lining up the binary point for arithmetic, and fixed-point numbers are display incorrectly both in &lt;span style="font-family:courier new;"&gt;$display&lt;/span&gt;s and in waveform viewers.&lt;br /&gt;&lt;br /&gt;Should verilog support fixed-point arithmetic?  Could you do something with structs and operator overloading in SystemVerilog? (Maybe not for synthesis).  It turns out that I don't have solutions or recommendations for any of this, so this was just a rant. Sorry about that...&lt;br /&gt;&lt;br /&gt;All this does mean that a lot of the high-level datapath design must be done in Matlab or whatever.  I hope Matlab has fixed-point libraries...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;An Aside: Text Macros&lt;/h3&gt;Why do none of my simulators happily accept the following?&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;b&gt;`define two_lsbs(a) a[1:0]&lt;/b&gt;&lt;br /&gt;module mess();&lt;br /&gt;   reg [3:0] some_vector;&lt;br /&gt;   initial begin&lt;br /&gt;      $display( "%b", &lt;b&gt;`two_lsbs(some_vector)&lt;/b&gt; ); // OK&lt;br /&gt;      $display( "%b", &lt;b&gt;`two_lsbs(5)&lt;/b&gt; ); // broken&lt;br /&gt;   end&lt;br /&gt;endmodule&lt;/pre&gt;&lt;br /&gt;When you go to use this, simulators complain about unmatched parenthesis when a numeric literal is supplied. Why?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7763117497297224225-1635520865087983523?l=amakersblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/1635520865087983523/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7763117497297224225&amp;postID=1635520865087983523' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/1635520865087983523'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/1635520865087983523'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/2008/07/fixed-point-arithmetic-with-verilog.html' title='Fixed-Point Arithmetic with Verilog'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_nw9n44o883o/SId8NCyGh4I/AAAAAAAAAAU/etVoBi27Vrc/s72-c/fractional.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763117497297224225.post-5510967065630809896</id><published>2008-06-03T17:32:00.000-07:00</published><updated>2009-01-15T21:07:13.229-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><category scheme='http://www.blogger.com/atom/ns#' term='RTL Visualiser'/><title type='text'>Drawing Circuit Diagrams</title><content type='html'>If you've been browsing some of my previous posts, you'll know that I'm interested in writing an open source tool to generate schematics from some Verilog RTL.  And you'll also probably remember that I was trying to come up with the layout &amp;amp; routing algorithms for the schematics myself.&lt;br /&gt;I'm also failing miserably, you may remember. This is as far as I got with the &lt;a href="http://amakersblog.blogspot.com/2007/12/rtl-visualiser.html"&gt;genetic algorithm layout&lt;/a&gt; before I decided to abandon it on speed and reproducability grounds:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e){}" href="http://2.bp.blogspot.com/_nw9n44o883o/SEXmTUDh-5I/AAAAAAAAAAM/3PGBofXZAJY/s1600-h/Screenshot-spider-3.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_nw9n44o883o/SEXmTUDh-5I/AAAAAAAAAAM/3PGBofXZAJY/s320/Screenshot-spider-3.png" alt="" id="BLOGGER_PHOTO_ID_5207821763599268754" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So, I've honoured the pragmatic promise I made to myself, and I've turned to the interwebs for help. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Vocabulary&lt;/h2&gt;Drawing automated pictures of relationships in Computer Science goes by the name of &lt;i&gt;&lt;a href="http://en.wikipedia.org/wiki/Graph_layout"&gt;Graph Drawing&lt;/a&gt;&lt;/i&gt;, a branch of &lt;i&gt;Graph Theory&lt;/i&gt;. According to this stuff, I'm looking to draw &lt;i&gt;Layered Orthogonal Directed Graphs&lt;/i&gt;:&lt;ul&gt;&lt;li&gt;'Layered' from the fact that I can arrange the instances into columns.  Sugiyama seems to be the main man when it comes to algorithms for this sort of graph.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;'Orthogonal' because I want the nets to go in right-angles.&lt;/li&gt;&lt;li&gt;'Directed' because there's a flow in the drawing.  For us EEs, this flow is left to right, but in graph theory it's usually top to bottom.  So my problem would've been with the x-placement.&lt;/li&gt;&lt;/ul&gt; In graph theory, my RTL module instantiations are &lt;i&gt;nodes&lt;/i&gt; and nets are &lt;i&gt;edges&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Existing Code&lt;/h2&gt;The first thing I did with my new-found pragmatism was to look for open-sourced code I could &lt;strike&gt;rob&lt;/strike&gt; use. Preferably this code would be a C/C++ library (for speed) with Python bindings (for handiness), but I'd settle for pure Python. I didn't find exactly what I was looking for; either there was a lack of examples and screenshots, no python bindings, or the library was closed source.  That said, if I'm willing to learn SWIG to create python bindings, or I'm willing to create my own examples, there are a few libraries to investigate further:&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.ogdf.net/ogdf.php"&gt;OGDF&lt;/a&gt;: C++&lt;/li&gt;&lt;li&gt;&lt;a href="https://networkx.lanl.gov/wiki"&gt;networkx&lt;/a&gt;: Python&lt;/li&gt;&lt;li&gt;&lt;a href="http://cneurocvs.rmki.kfki.hu/igraph/"&gt;igraph&lt;/a&gt;: Python binding of C library.&lt;/li&gt;&lt;/ul&gt;Some of the proprietary stuff could've been exactly what I need: &lt;a href="http://www.tomsawyer.com/images/gallery.php?postid=session0.83786000%201212536326&amp;amp;click=enlarge10"&gt;tomsayer.com&lt;/a&gt;  (sorry, this tries to resize your browser window) had a teaser of a circuit diagram, and yFiles had intrigingly-named &lt;a href="http://www.yworks.com/products/yfiles/doc/developers-guide/channel_edge_router.html"&gt;ChannelEdgeRouter&lt;/a&gt; class.&lt;br /&gt;&lt;br /&gt;Even if none of the above open source libraries end up suiting my project, at least I have the freedom to look at the code and study the algorithms they use when cooking my own.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Literature Search&lt;/h2&gt;Then I stuck a whole pile of terms into the search engine to see what turned up.  I tried various combinations of terms including 'graph', 'drawing', 'routing', 'layout', 'channel', 'layered', '2d' etc. and added more as they turned up.  Although I got some useful introductory slide decks from university courses, I did bang my head up against sites such as &lt;a href="http://ieeexplore.ieee.org/"&gt;ieeexplore&lt;/a&gt; and &lt;a href="http://www.springerlink.com/"&gt;springerlinks&lt;/a&gt; which expected me to pay for stuff. &lt;br /&gt;&lt;br /&gt;The searching did throw up a pair of papers by Eschbach, Günther &amp;amp; Becker which seem promising. One of which, &lt;span style="font-style: italic;"&gt;Orthogonal Circuit Visualization Improved by Merging the Placement and Routing Phases&lt;/span&gt;, especially so.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Homework&lt;/h2&gt;I think the next stage of my endeavour is to read the papers by EGB (hehe, Eternal Golden Braid) I mentioned above, and have a look into those graph drawing libraries, maybe igraph seems the most appealing at a first cut.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7763117497297224225-5510967065630809896?l=amakersblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/5510967065630809896/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7763117497297224225&amp;postID=5510967065630809896' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/5510967065630809896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/5510967065630809896'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/2008/06/drawing-circuit-diagrams.html' title='Drawing Circuit Diagrams'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_nw9n44o883o/SEXmTUDh-5I/AAAAAAAAAAM/3PGBofXZAJY/s72-c/Screenshot-spider-3.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763117497297224225.post-252618021078520751</id><published>2008-05-27T10:44:00.001-07:00</published><updated>2008-05-27T11:59:37.721-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='asic verification'/><category scheme='http://www.blogger.com/atom/ns#' term='systemverilog'/><category scheme='http://www.blogger.com/atom/ns#' term='verilog'/><title type='text'>Constrained Random Verification</title><content type='html'>After stewing for a bit on constrained random verification, it's beginning to loose a bit of its sheen.  Let me explain...&lt;br /&gt;&lt;br /&gt;The first question is: What gets randomised?  Well, there are two types of inputs to our chips: control and data, ignoring supplies.  So let's think about what randomizing control and data inputs might entail.&lt;br /&gt;&lt;br /&gt;&lt;H3&gt;Randomizing Control Inputs&lt;/H3&gt;For control input we can randomise timing, order or address-data pairs.  Randomising the timing between control writes caught bugs for us in the past, so we find this useful.  Randomising the order of control writes doesn't make sense for us as we give customers specific powerup sequences to avoid various unwanted transients.&lt;br /&gt;&lt;br /&gt;Throwing constrained random address-data pairs at the chip seems like A Good Thing, but there's a lot of infrastructure needed to get at the full benefits.  At the minimum you'll need a high-level model of your chip against which you can check the behaviour of your chip.  But the very point of high-level models is that they are not as complicated as the chip itself.  I worry in this case that we'll end up designing each chip twice - once in RTL and once as a model.  I may be getting confused here, so I should try to gather my thoughts on high-level modelling at a later time.&lt;br /&gt; &lt;br /&gt;&lt;H3&gt;Randomizing Data Inputs&lt;/H3&gt;I'm failing to see the benefits of randomizing the input to datapaths.  I've issues with the high-level modelling again, and anyway truely random data is nonsense when piped through filters! (GIGO).  So how would constrained random data look like? Usual signals with noise on top?  'Usual signals' is what we're trying to do away with though... (Could I use that trick where you can set a maximum dx/dt?)&lt;br /&gt;&lt;br /&gt;I'm not sure what constrained random input signals would look like in our case.  And I'm not sure what type of errors they could catch in the datapath (assuming we already stress them with types of signals that we know can over-range our sums).&lt;br /&gt;&lt;br /&gt;&lt;H3&gt;Random Chip Configurations&lt;/H3&gt;Maybe I'm thinking about this at too low a level.  Maybe we should be randomizing the &lt;i&gt;configurations&lt;/i&gt; of our chips.  For example, our serial data ports can work in a variety of modes: I2S, LJ, RJ etc.  We've sims to check the correct functionality of each of these serial formats.  But when it comes to other sims, for example, checking out the DAC signal chain, we usually feed it with data in the default serial format (I2S).  Maybe it's things like serial formats and number of DACs powered up that should be randomised?  Maybe that's a bad example as the interfaces between our serial ports and the rest of the chip are well defined?&lt;br /&gt;&lt;br /&gt;&lt;H3&gt;Conclusion&lt;/H3&gt;I haven't come to one, really - the jury's looking to get put up in a plush hotel.  I might explore the randomisation of our chips' configurations and maybe make sure we're stressing our datapaths.  And I haven't even touched upon functional coverage, which if I'm not careful, could fall prey to the same traps as code coverage.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7763117497297224225-252618021078520751?l=amakersblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/252618021078520751/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7763117497297224225&amp;postID=252618021078520751' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/252618021078520751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/252618021078520751'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/2008/05/constrained-random-verification.html' title='Constrained Random Verification'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763117497297224225.post-1175561814407292281</id><published>2008-05-16T10:58:00.000-07:00</published><updated>2008-05-16T13:51:51.441-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='systemverilog'/><category scheme='http://www.blogger.com/atom/ns#' term='verilog'/><title type='text'>SystemVerilog</title><content type='html'>I've just come back from a week-long &lt;a href="http://www.systemverilog.org/"&gt;SystemVerilog&lt;/a&gt; course, presented by one of the folks at &lt;a href="http://www.doulos.com/"&gt;Doulos&lt;/a&gt;.  The course was, I'd have to admit, very interesting and extreemly well delivered - J_ certainly knew his stuff.  There seems to be a lot of cool features in SystemVerilog, and other slightly underwhelming stuff, that I want to rant about.&lt;h3&gt;A Fistfull of Features...&lt;/h3&gt;SystemVerilog is basically Verilog 2001 with a shedload of new ideas, features and keywords, system tasks, mini-languages, etc, etc.  Although there are one or two new language features to make your RTL look prettier, to my mind the majority of the shiny new things are for verification engineers.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Good&lt;/h3&gt;I'm mostly a verification engineer, and SystemVerilog offers me 3 huge and genuinely exciting powers that I want to try out right away; these being assertions, constrained random testing and functional coverage.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Assertions&lt;/h4&gt;Assertions are great for making sure your design does what you wanted it to do.  They can check the value of a signal or two at a point in time.  But more interestingly, by using a regular-expression type mini-language, they can also check signal behaviour during a sequence of clock cycles.&lt;br /&gt;&lt;br /&gt;The idea is that you sprinkle assertions all around your RTL in interesting places (synthesis tools will ignore them), and they'll let you know if whatever they're monitoring steps out of line.  They'll also help you get to the source of a bug far quicker than a traditional chip-as-a-black-box testbench setup - in which case you have to wait for bugs to propagate to the outputs, then follow the chain of events back to the bug.&lt;br /&gt;&lt;br /&gt;Another win for assertions is when you code up a module, and a colleague ends up using it.  If the module has assertions on its inputs, it can complain if it is not being fed with the correct signals.  Now any bugs that are reported to you are real bugs, and your time is not wasted with bugs due to a misunderstanding of the module's input specs.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Functional Coverage&lt;/h4&gt;Functional is a new angle on design verification.  Currently our verification plans consists of a big list of sims that must pass before we can tape out.  This list is mostly derived from the specs - we go through the specs and try to write a sim testcase that will cover each bit of functionality.&lt;br /&gt;&lt;br /&gt;Functional coverage is different because first up, you describe to the simulator every  bit of functionality that you want to see. Then it tells you what behaviours in your list it has encountered during the course of a sim (coverage results are usually aggregated over a bunch of sims).  If you're careful when writing the functionality descriptions, you can say that functional verification is finished when 100% of targets are hit!&lt;br /&gt;&lt;br /&gt;The big payoff for functional coverage is when it's used with constrained random testing.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Constrained Random Testing&lt;/h4&gt;Constrained random testing makes it possible to trade verification engineer brain cycles for CPU cycles. It involves throwing random-yet-tuned stimulus at your design, shaking the innards of the chip in more ways than any verification engineer could engineer given a reasonable amount of time.&lt;br /&gt;&lt;br /&gt;The fun starts when assertions are added to our design and our list of functional coverage points has been defined.  Instead of tuning bunches of testcases to exercise each behaviour, we can just run a few randomised testbenches for longer and let luck stumble across all our behaviours. (Could we breed testcases?) Of course, purely random stimulus is not going to be helpful here due to the GIGO principle, hence we guide or constrain the randomness. And we're probably going to need a bus functional model to check the outputs of our design too.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Bad and The Ugly&lt;/h3&gt;This is where I descend into rant mode, so be warned...&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;The Tower of Babel&lt;/h4&gt;Nothing in SystemVerilog is new under the sun, everything has been magpied from elsewhere: assertions are based on Sugar; OOP sort of follows C++; and other bits and pieces from OpenVera, Superlog and other things I can't quite remember.  This leaves the whole SystemVerilog thing looking a bit un-integrated (or uneven, or inconsistent) to me.  In most places you use begin-end, other places you use curly brackets.  In most places you finish lines off with a semi-colon, in constraint blocks you don't.  While in some cases this is not too bad and is perfectly understandable (for example, the PSL), for the most part it just feels a bit of a hodge-podge mish-mash in places.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Classes&lt;/h4&gt;OK, I can see how this might get slightly controversial, and maybe this is more related to the inconsistency I've already noted, but I think that object orientated programming has been kludged into SystemVerilog.  And it's an ugly kludge.&lt;br /&gt;&lt;br /&gt;The amount of hoops that need to be jumped through just to use a class in SystemVerilog that wiggles a few pins, and keeping it reusable is crazy! First, define an interface, give it a clocking block and a modport, throw the handle to the interface all around the place, instanciate your classes, interfaces, and DUT, and probably a few other things that I've forgotten too.&lt;br /&gt;&lt;br /&gt;OK, so you only have to do all this once, but it seems ugly and unintuitive.  The concurrency that's an essential feature of an HDL is lost for classes and has to be regained again by forking a .run() method on all your classes.  The connectivity that's an essential feature of an HDL is lost and has to be faked by using references to interfaces though which pins are accessed.  Crazy.&lt;br /&gt;&lt;br /&gt;Could us poor hardware engineers not be introduced to the benefits of object orientated programming in a gentler way?  Why can't modules not be our 'classes', and be inhierited as well as being instantiated?  I've a nagging feeling that I'm missing something huge about the way OOP needs to be implemented, and that maybe it had to be done that way - I'd love to know why.&lt;br /&gt;&lt;br /&gt;&lt;H3&gt;A Few Features More&lt;/H3&gt;&lt;br /&gt;Overall, I'm genuinely excited by some of the possiblities that SystemVerilog has opened up to our verification setups.  I plan to try out some of these things in our current testbench and report on the progress - I won't be changing it to a class-based architecture any time soon though!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7763117497297224225-1175561814407292281?l=amakersblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/1175561814407292281/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7763117497297224225&amp;postID=1175561814407292281' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/1175561814407292281'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/1175561814407292281'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/2008/05/systemverilog.html' title='SystemVerilog'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763117497297224225.post-7811176068704633326</id><published>2008-03-05T14:16:00.000-08:00</published><updated>2010-01-14T13:59:47.918-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='verilog'/><title type='text'>Some Verilog Tips &amp; Tricks</title><content type='html'>I thought I'd share a few Verilog tips &amp;amp; tricks I discovered recently that help when you're trying to build a simulation that doesn't care where it's run from in your directory structure.&lt;br /&gt;&lt;h2&gt;Gather Files &amp;amp; Environmental Variables&lt;/h2&gt;Gather files are list of simulator commands that are included using the -f flag.  You know this, but you may have a different name for them. In these gather files I list all the Verilog module files that I'm using in the simulation, as well as the include directories needed.  I specify each file relatively (eg ../../../) from a simulation base directory ($BASEDIR).  I actively avoid absolute paths: this gives designers the freedom to set up their simulations anywhere; and the simulations can be run from any of our company's sites. So long, of course, if the designer checks the code out from our versioning system...&lt;br /&gt;&lt;br /&gt;run_sim.sh:&lt;br /&gt;&lt;pre&gt;#! /usr/bin/sh&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;export BASEDIR="../../../" # setenv in csh&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;simulator -f "${BASEDIR}/config/sim.gather"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;${BASEDIR}/config/sim.gather:&lt;br /&gt;&lt;pre&gt;//&lt;br /&gt;// TITLE: A Simulation Gather File&lt;br /&gt;//&lt;br /&gt;+incdir+&lt;span style="font-weight:bold;"&gt;${BASEDIR}&lt;/span&gt;/block1&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;${BASEDIR}&lt;/span&gt;/block1/rtl/module1.v&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;${BASEDIR}&lt;/span&gt;/block1/rtl/module2.v&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;${BASEDIR}&lt;/span&gt;/block2/rtl/module1.v&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;${BASEDIR}&lt;/span&gt;/block2/rtl/module2.v&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The magic here is the 'export' command in the shell script.  For best results, the script calling the simulator can calculate what this should be based on the current working directory ($PWD).  Verilog &amp;amp; Debussy will correctly substitute any environmental variables it sees in gather files.  Our designs are fairly complicated, and I've used nested gather files sucessfully to mimic Verilog-2001's 'Configurations'.  But don't get me started on using Verilog configurations with NC-Verilog and Debussy...&lt;br /&gt;&lt;br /&gt;&lt;H2&gt;Specifying bitmap files for $readmemb and $readmemh&lt;/H2&gt;The next problem is making any bitmap files for $readmem tasks portable.  The main problem here is that macros are not expanded within strings, nor are you allowed to split strings with them.  For example, the code below won't work:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;`define BASEDIR ../../../&lt;br /&gt;`define BASEDIR_STR "../../../    // may not even get this far...&lt;br /&gt;&lt;br /&gt;module test();&lt;br /&gt;  reg [3:0] mem [3:0];&lt;br /&gt;&lt;br /&gt;  initial begin&lt;br /&gt;    $readmemh("&lt;span style="font-weight:bold;"&gt;`BASEDIR&lt;/span&gt;/rom.dat"); // macro won't be expanded&lt;br /&gt;    $readmemb(&lt;span style="font-weight:bold;"&gt;`BASEDIR_STR&lt;/span&gt;.rom.dat"); // won't be accepted by simulator - split over string&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;endmodule&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I came up with a solution using a reg vector to hold a strings and then using $sformat, but it seemed ugly and I thought there must be a better way.  And I found it using concatenations.&lt;br /&gt;&lt;pre&gt;module test();&lt;br /&gt;  reg [3:0] mem [3:0];&lt;br /&gt;&lt;br /&gt;  initial begin&lt;br /&gt;    $readmemb(&lt;span style="font-weight:bold;"&gt;{`BASEDIR_STR,"/rom.dat"}&lt;/span&gt;); // string literal concatenation!&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;endmodule&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This works like a charm so long as `BASEDIR_STR is a string literal - "../" is ok but just ../ is not.  To keep things directory-agnostic, I pass the base directory string as an argument to the simulator, eg (escaping the quotes is important here to get the path passed to the simulator as a string literal):&lt;br /&gt;&lt;br /&gt;run_sim.sh:&lt;br /&gt;&lt;pre&gt;#! /usr/bin/sh&lt;br /&gt;export BASEDIR="../../../" # setenv in csh&lt;br /&gt;&lt;br /&gt;simulator -f \&lt;br /&gt;  "${BASEDIR}/config/sim.gather" \&lt;br /&gt;  &lt;span style="font-weight:bold;"&gt;+define+BASEDIR_STR=\"${BASEDIR}\"&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7763117497297224225-7811176068704633326?l=amakersblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/7811176068704633326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7763117497297224225&amp;postID=7811176068704633326' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/7811176068704633326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/7811176068704633326'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/2008/03/some-verilog-tips-tricks.html' title='Some Verilog Tips &amp; Tricks'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763117497297224225.post-2486435693221501159</id><published>2007-12-10T22:02:00.001-08:00</published><updated>2007-12-10T22:46:40.055-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Y-Placement'/><category scheme='http://www.blogger.com/atom/ns#' term='very basic'/><category scheme='http://www.blogger.com/atom/ns#' term='RTL Visualiser'/><title type='text'>RTL Visualiser</title><content type='html'>I'm in the midst of writing a Visualiser for Verilog RTL.  It'll take in a Verilog description of a circuit design and produce the corresponding schematics.  I hope it will be a joy to use, and produce 'nice' schematics.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt; &lt;h2&gt;Automatic Schematics&lt;br /&gt;&lt;/h2&gt;I've found that producing nice automatic schematics is difficult.&lt;br /&gt;&lt;br /&gt;As for the App: so far, I have a very basic GUI running. It reads in and parses very basic verilog, builds the hierarchy tree and displays very basic schematics of very basic RTL, with very basic ratsnest type flightlines representing the block-to-block connections. It's all very basic. I've a nice recursive algorithm to place module instantiations in the x-axis, but y-axis placement is a whole other ball game. Y-Placement is not very basic. (At least as far as I can tell).&lt;br /&gt;&lt;br /&gt;I've been fighting with the Y-Placement problem on-and-off for over 4 months, with no successful outcome. I want to see what I'm capable from a programming design point-of-view, so I have not yet consulted the interweb on how to solve it.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Genetic Algorithms&lt;/h2&gt;Another interest of mine is in Genetic Algorithms, so I threw one at it, to see if it could get some nice y-axis values to stick. The GA was s.l.o.w. (about a minute to place ~13 blocks - this is far from 'joy to use' territory), although there is room for some tuning to speed things up.  And even though it successfully minimized net crossovers, it did not minimise them all. Also, things that should've been connected with a straight line weren't.&lt;br /&gt;&lt;br /&gt;This led me to think about Genetic Algorithms and when it's a good idea to use them.  But I never came to any conclusions, except to say that its probably a bad idea for this app.  It's a bad idea for a few reasons.&lt;br /&gt;&lt;br /&gt;First of all, there's the speed issue.  I'm not convinced that even if I farmed the GA out to a 'C' routine, that I'd get through enough genotypes and generations in a GUI-friendly timeframe to get a nice schematic. And since the length of the genome depends directly on the number of things I have to find a y-axis number for, the GA slows down exponentially as this size increases.  With the added complication of having to find heuristics to determine what population size and how many generations to run the GA for per genome size, it all just gets too much to deal with.&lt;br /&gt;&lt;br /&gt;Another issue with running a GA here is that there's no guarantee that you'll always hit a genome with 'maximum' fitness (ie no crossovers if there needn't be, etc).  And due to the nature of the algorithm, you can't get consistent schematics for the same RTL  for each GA run if you can't consistently hit the fitness maxima.&lt;br /&gt;&lt;br /&gt;The fitness functions used for the GA seems to take up the most programming time. And, how in hell do you write a fitness function for 'nice schematics'?  To produce nice schematics, I think it's necessary to minimize net crossovers and ensure that modules are not drawn over the top of each other. It also seems to be important to minimize the gradient (sum of the gradients) of the connections. I have included these measures in the fitness function, and have even tried tweaking the weighting given to each, but all to not much avail.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;So?&lt;/h2&gt;So I've gone back to basics, and am going to try to draw simple 2 &amp;amp; 3 gate circuits to see if I can get a handle on automatic schematics. Wish me luck...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7763117497297224225-2486435693221501159?l=amakersblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/2486435693221501159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7763117497297224225&amp;postID=2486435693221501159' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/2486435693221501159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/2486435693221501159'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/2007/12/rtl-visualiser.html' title='RTL Visualiser'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763117497297224225.post-1691958393154206126</id><published>2007-08-27T09:48:00.000-07:00</published><updated>2007-08-27T10:09:09.190-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='subversion'/><category scheme='http://www.blogger.com/atom/ns#' term='samba'/><category scheme='http://www.blogger.com/atom/ns#' term='RTL Visualiser'/><title type='text'>BEDROOMNET: Subversion &amp; Samba</title><content type='html'>As I mentioned on a previous post, one of the projects I have on the go is an RTL Visualiser.  As I want this to be cross-platform, I suppose I had better test it on a few platforms.  To this end, I set up a small local network where my mintLinux desktop could talk to my XP laptop.  The idea was to host a Subversion repository on the desktop, where I'd be doing most of the development, and use a mix of Samba, Subversion and TortoiseSVN to get the XP laptop to access the repo.&lt;br /&gt;&lt;h3&gt;Samba&lt;/h3&gt;Out of the box (and with a crossover cable) the desktop could read shared folders on the laptop, but the laptop couldn't see the desktop.  So after installing Samba, running the Network Setup Wizard on the laptop and sharing a few folders on both machines, things were running well.  I think I disabled the password stuff on Samba because I still haven't figured out how to add accounts - I don't need them anyway for this network.  I'll poke about on it a bit more once I fork out for an internet connection.&lt;br /&gt;&lt;h3&gt;Subversion&lt;/h3&gt;Getting this running was fairly easy too.  First I installed Subversion on the desktop and set up a repository on an ext3 partition.  Then I installed TortoiseSVN on the laptop - a SVN client program which hooks into Windows explorer and gives extra SVN command options when you right-click on a folder or file.  After this, I easily checked out the SVN repo on the laptop and ran my RTL Visualiser (Version 0.1!) successfully on the laptop!&lt;br /&gt;&lt;br /&gt;I couldn't check any changes in though. But after adding a user and a password to the repo's passwd file and enabling password authentication, I was soon checking stuff into the desktop repo from the laptop.&lt;br /&gt;&lt;h3&gt;At the end of the day...&lt;/h3&gt;All in all I'm fairly happy with this setup, and it wasn't too difficult to set up after doing a bit of digging around in the Subversion docs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7763117497297224225-1691958393154206126?l=amakersblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/1691958393154206126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7763117497297224225&amp;postID=1691958393154206126' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/1691958393154206126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/1691958393154206126'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/2007/08/bedroomnet-subversion-samba.html' title='BEDROOMNET: Subversion &amp; Samba'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763117497297224225.post-163063091846928599</id><published>2007-08-21T13:36:00.000-07:00</published><updated>2007-08-21T13:58:59.079-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linuxmint'/><category scheme='http://www.blogger.com/atom/ns#' term='openoffice'/><category scheme='http://www.blogger.com/atom/ns#' term='drivers'/><title type='text'>LinuxMint</title><content type='html'>&lt;h3&gt;Distros and Me&lt;/h3&gt;As mentioned in my last post, I had a rotten time trying to find a linux distro that suited me straight out of the box.  I suppose this is a big ask, but the reasoning behind it is that I know I'm going to want to try out tons of distros, but I don't want to have to go thru the hassle of configuring it to suite each time.  I suppose I'm going to have to settle on one distro for "everyday use" and leave the other ext3 partition on my harddrive for my new distro fixes.  I've settled on LinuxMint (MintLinux??) 'cos I like the codec support and the themes and I like the fact that it can use the Ubuntu repos.&lt;br /&gt;&lt;h3&gt;NVIDIA Drivers&lt;/h3&gt;&lt;a href="http://www.lugradio.org/"&gt;I hate freedom&lt;/a&gt;, and I want my NVIDIA drivers.  My Linux box remains unconnected to the net, which makes it a pain to install the NVIDIA drivers on LinuxMint. Luckily, &lt;a href="http://linuxmint.com/forum/viewtopic.php?t=3940"&gt;I stumbled across an easy fix&lt;/a&gt; for installing NVIDIA drivers. It requires a Ubuntu Fiesty CD (which matches LinuxMint Cassandra), which I got with a linux magazine...&lt;br /&gt;&lt;br /&gt;* Fire up Synaptic and disable all the repositories pointing to the web.&lt;br /&gt;* Select 'Add a CDROM' and insert the Ubuntu CD when prompted.&lt;br /&gt;* Close Synaptic.&lt;br /&gt;* Open Restricted Driver Manager.&lt;br /&gt;* Enable NVIDIA Drivers, which now it grabs from the CD drive.&lt;br /&gt;* (Reboot? - I can't remember exactly) &lt;br /&gt;&lt;h3&gt;OpenOffice&lt;/h3&gt;I've spotted a few funnies with the locale settings when using OpenOffice.  I selected Dublin, Ireland as my timezone (locale?) when installing LinuxMint.  I'm also assuming that the language packs that are installed depend on the locale in some logical way.  But unfortunately I had to manually install the help files and the dictionaries for OpenOffice.  It looks like the installer was looking for 'English (Ireland)' for example and could not find it, but it did not revert to 'English (UK)' or 'English (US)' and instead installed nothing.  I suppose what I'm getting at is that it'd be nice if there was some kind of graceful fallback for OpenOffice Help and Dictionary files.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7763117497297224225-163063091846928599?l=amakersblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/163063091846928599/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7763117497297224225&amp;postID=163063091846928599' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/163063091846928599'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/163063091846928599'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/2007/08/linuxmint.html' title='LinuxMint'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763117497297224225.post-8741886156956424620</id><published>2007-07-17T19:07:00.000-07:00</published><updated>2007-07-17T19:32:39.233-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='codecs'/><category scheme='http://www.blogger.com/atom/ns#' term='hassle'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='drivers'/><title type='text'>Linux: Codecs, Proprietary Drivers &amp; Hassle</title><content type='html'>I'm currently playing around with linux distros trying to find one that suites me.  I've a collection of coverdisks from linux mags, and I'm to-ing and fro-ing, installing the various flavours on my new computer. But I'm finding it *very* frustrating.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Vista&lt;/h3&gt;First of all, the box came with Vista pre-installed. And whatever else can be said about micros~1 - Vista looks great!  But I like my command line, so I reduced the Vista partition; created a few new ones and installed Ubuntu 7.04.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Ubuntu vs Media&lt;/h3&gt;My first impressions was that Ubuntu looks fairly ugly - or maybe 'old' is a better word - compared to Vista.  Ubuntu catches up with the 3D desktop effects, and after installing NVIDIA's proprietary drivers from the "Restricted Drivers" tool, everything was running smoothly.&lt;br /&gt;&lt;br /&gt;That was until I tried to play MP3's and the video tutorials from the guitar mag coverdisks I've lying around.   Unsucessfully - although in fairness Vista doesn't play MPEG4's or MOVs out of the box either.  I've no internet connection at home, so I can't use the automatic download tools to fetch the codecs.  Hunting around on the net gave me no clues on what packages to download - and even if I fire up Synaptic and ask it to write a download script I've still no idea what to ask it to download.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;LinuxMint vs Drivers&lt;/h3&gt;Then I heard of LinuxMint with it's bundled codecs.  So I ordered it from On-Disk and was pleased to see it arrive after only 4 days or so.  I much prefer the colour scheme, but again, things like the (IMHO) very poor icons make it look a bit rusty.  The mintMenu is fairly cool and friendlier that Ubuntu's two-panel approach.  But LinuxMint doesn't come with the *&amp;amp;^%£€&lt;¹!¡ NVIDIA drivers!!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I'm going to have to stop being such a tight-arse and get my home computer wired up to the web. Or wait until NVIDIA open-source their drivers...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7763117497297224225-8741886156956424620?l=amakersblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/8741886156956424620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7763117497297224225&amp;postID=8741886156956424620' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/8741886156956424620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/8741886156956424620'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/2007/07/linux-codecs-proprietary-drivers-hassle.html' title='Linux: Codecs, Proprietary Drivers &amp; Hassle'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763117497297224225.post-2016374893369182266</id><published>2007-06-01T10:16:00.000-07:00</published><updated>2007-06-01T10:19:55.430-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='sqlite'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Getting SQLite Working</title><content type='html'>Steps I needed to go through to be able to use SQLite in my python programs.  This was on my linux box, I haven't tried it on my micros~1 laptop...&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;Download python2.5 and compile.  This has the sqlite3 module built in - but it's only a wrapper!&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Download and compile sqlite3.  Initial trials bombed out when looking for 'tcl.h'.  I don't need TCL bindings, so a quick look on the sqlite wiki says to 'configure --disable-tcl'.  This seemed to do the trick.&lt;/li&gt;&lt;li&gt;As Python only includes the wrapper for sqlite, I needed to run the setup.py script again so that Python knows where to find the sqlite executable.  I needed to hack the setup.py because I'm not installing sqlite in the usual place.&lt;br /&gt;To do this, I searched setup.py for sqlite3 and added the sqlite build directory path to sqlite_inc_paths - it'll pick up sqlite3.h here.  Then, I added os.path.join(sqlite_incdir, '.libs') to the sqlite_dirs_to_check list - my libraries were linked into bld/.libs&lt;/li&gt;&lt;li&gt;Running Python again and doing a 'import sqlite3' is quiet - which means no errors! Job done.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7763117497297224225-2016374893369182266?l=amakersblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/2016374893369182266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7763117497297224225&amp;postID=2016374893369182266' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/2016374893369182266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/2016374893369182266'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/2007/06/getting-sqlite-working.html' title='Getting SQLite Working'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763117497297224225.post-5282836635640066799</id><published>2007-05-30T19:47:00.000-07:00</published><updated>2007-07-17T19:37:28.276-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><title type='text'>Projects</title><content type='html'>&lt;h3&gt;I've a few projects I'd like to do:&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;USB Audio Interface&lt;/li&gt;&lt;ul&gt;&lt;li&gt;for hooking up my guitar to my computer&lt;/li&gt;&lt;li&gt;using those fancy PICs&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;A darts scoring system&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Just to use those *HUGE* LEDs&lt;/li&gt;&lt;li&gt;Would suite my mates' "Bar and Darts" room.&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Projects in the works&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;RTL visualiser&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Python and wxWidgets&lt;/li&gt;&lt;li&gt;inspired by Nova's Debussy&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h3&gt;Projects I've recently completed:&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Multi-Zone Lighting Controller for a friend's new gaff.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;PICs, keypads and high-voltages!&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7763117497297224225-5282836635640066799?l=amakersblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/5282836635640066799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7763117497297224225&amp;postID=5282836635640066799' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/5282836635640066799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/5282836635640066799'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/2007/05/projects.html' title='Projects'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763117497297224225.post-760374646133127798</id><published>2007-05-30T19:35:00.000-07:00</published><updated>2007-07-17T19:33:58.983-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pic'/><title type='text'>My Code vs the PIC16F871 Linker Script</title><content type='html'>&lt;p&gt;Just wasted a day trying to port some PIC code over from a PIC16F684 to a 16F871. It was all down to the linker script, and my hazy understanding of where the linker tries to place data. First a few basic facts about the directives for specifying relocatable memory blocks:&lt;br /&gt;&lt;/p&gt; &lt;ul&gt;&lt;li&gt;UDATA: Uninitialised data which is placed in sections defined as "DATABANK" in the linker scripts.  These sections are 'banked' memory locations, so you have to be careful to select the correct bank before accessing the data at these memory locations.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;UDATA_SHR: Uninitialised shared data which is placed in sections defined as "SHAREBANK" in the linker scripts.  These sections are 'unbanked', which means you don't need to care too much which bank you've selected when using these data locations. The data accessed at this location is the same across all banks.&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;The All-Important Linker Script&lt;br /&gt;&lt;/h3&gt; My assembler code is split across a few files, with some of the files defining a few variables in UDATA blocks.  This was all cool when I was targeting the code to the 18F684, but when I targeted it to the 16F871, I got the error message:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Error - section '.udata' can not fit the section.  Section '.udata' length=0x00000012&lt;/pre&gt;&lt;br /&gt;After some vigorous interweb searching, I finally hit on the answer - the 16F871 linker script doesn't define any DATABANK sections!  The linker had nowhere to put my UDATA.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Fix&lt;/h3&gt; Instead of hacking the linker file, which I was tempted to do, I changed all my UDATA blocks to UDATA_SHR.  One of my files had UDATA and UDATA_SHR blocks, so I had to edit this 'cos you're only allowed one block of each type per file.&lt;br /&gt;&lt;br /&gt;Now it links like a dream!  Needless to say, there are now copious comments in the code...&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;References:&lt;/h4&gt; &lt;ul&gt;&lt;li&gt;&lt;a href="http://www.linuxhacker.org/cgi-bin/ezmlm-cgi/1/3312"&gt;http://www.linuxhacker.org/cgi-bin/ezmlm-cgi/1/3312&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://forum.microchip.com/printable.aspx?m=57615"&gt;http://forum.microchip.com/printable.aspx?m=57615&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;  &lt;h1&gt;&lt;br /&gt;&lt;/h1&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7763117497297224225-760374646133127798?l=amakersblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://amakersblog.blogspot.com/feeds/760374646133127798/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7763117497297224225&amp;postID=760374646133127798' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/760374646133127798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763117497297224225/posts/default/760374646133127798'/><link rel='alternate' type='text/html' href='http://amakersblog.blogspot.com/2007/05/my-code-vs-pic16f871-linker-script.html' title='My Code vs the PIC16F871 Linker Script'/><author><name>Marty</name><uri>http://www.blogger.com/profile/09291544028617899870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
