I finally had time to directly measure the rise and fall times of the CLK1 and CLK2 signals on my i4004 Instruction Pointer board. I'm hoping this will help me decide how to distribute these signals to the five boards of my i4004 CPU.
I finally had time to directly measure the rise and fall times of the CLK1 and CLK2 signals on my i4004 Instruction Pointer board. I'm hoping this will help me decide how to distribute these signals to the five boards of my i4004 CPU.
KiCad v5 added a feature that made creating custom footprint pad shapes really easy. You can incorporate primitive shapes like arcs and lines into a pad very easily.
To create this footprint I first created a new custom pad consisting of a tiny rectangular pad anchor, and added to that an arc and five horizontal lines. I added one of these pads on the left side of the footprint. Then placed a second on the right side of the footprint and rotated it 180 degrees. The result is this interlocking fingers pattern.
The only thing I had to fiddle with is the solder mask opening. You don't want any solder mask in the area where the conductive pad contacts the copper, and I didn't see how to force such an opening in the footprint. I ended up just widening the solder mask margin on the pads to the point where the apertures overlapped, but there is probably a better way to do this.
Bear in mind that exposed copper will oxidize fairly quickly if left exposed to air for very long. This would likely cause problems in the operation of such a switch. The original PCB used what appears to be conductive carbon rather than copper on that side of the board. Another option would be hard gold plating over nickel. Either would produce a long-lasting switch contact.
Since this is just a hobby project, I opted for standard ENIG (Electroless Nickel Immersion Gold) as a PCB finish and didn't attempt any other sort of protection for the switch contacts. This is not as durable as a hard gold plating, and would probably not be appropriate for a commercial product. But it's better than untreated copper, and provides a far more uniform surface than HASL (Hot Air Solder Leveling).
There really is no reason for the circular shape except that it matched the shape of the footprint on the original PCB I was replacing. Others have pointed out that a rectangular shape would have worked just as well and been a bit easier to create. But I liked the round shape so that's what I created.
Here's the contents of the Button_Round_6m3.keycad_mod file produced by KiCad 5.1:
(module Button_Round_6mm3 locked (layer F.Cu) (tedit 5AE33A01) (solder_mask_margin 0.3) (attr virtual) (fp_text reference REF** (at 0 5.6) (layer F.SilkS) (effects (font (size 1 1) (thickness 0.15))) ) (fp_text value Button_Round_6mm3 (at 0 -4.6) (layer F.Fab) (effects (font (size 1 1) (thickness 0.15))) ) (fp_circle (center 0 0) (end 3.5 0) (layer F.Fab) (width 0.15)) (fp_circle (center 0 0) (end 3.5 0) (layer F.CrtYd) (width 0.15)) (fp_circle (center 0 0) (end 3.5 0) (layer F.SilkS) (width 0.15)) (fp_circle (center 0 0) (end 3.5 0) (layer B.SilkS) (width 0.15)) (fp_circle (center 0 0) (end 3.5 0) (layer B.Fab) (width 0.15)) (pad 1 connect custom (at -3 0) (size 0.3 0.3) (layers F.Cu F.Mask) (zone_connect 0) (options (clearance outline) (anchor rect)) (primitives (gr_arc (start 3 0) (end 0 0) (angle 115.8) (width 0.3)) (gr_line (start 0.015 -0.3) (end 5.381 -0.3) (width 0.3)) (gr_line (start 0.402 -1.5) (end 4.873 -1.5) (width 0.3)) (gr_line (start 1.692 -2.7) (end 4.308 -2.7) (width 0.3)) (gr_arc (start 3 0) (end 0 0) (angle -44.4) (width 0.3)) (gr_line (start 0.138 0.9) (end 5.225 0.9) (width 0.3)) (gr_line (start 0.858 2.1) (end 4.162 2.1) (width 0.3)) )) (pad 2 connect custom (at 3 0 180) (size 0.3 0.3) (layers F.Cu F.Mask) (zone_connect 0) (options (clearance outline) (anchor rect)) (primitives (gr_arc (start 3 0) (end 0 0) (angle 115.8) (width 0.3)) (gr_line (start 0.015 -0.3) (end 5.381 -0.3) (width 0.3)) (gr_line (start 0.402 -1.5) (end 4.873 -1.5) (width 0.3)) (gr_line (start 1.692 -2.7) (end 4.308 -2.7) (width 0.3)) (gr_arc (start 3 0) (end 0 0) (angle -44.4) (width 0.3)) (gr_line (start 0.138 0.9) (end 5.225 0.9) (width 0.3)) (gr_line (start 0.858 2.1) (end 4.162 2.1) (width 0.3)) )) )
This article assumes you already have Xilinx ISE 14.7 installed and running on your system. If not, follow the instructions in this article, which are still valid for Ubuntu 20.04.
There are two issues with running iMPACT from ISE 14.7 on an Ubuntu 20.04 system (similar problems exist with 18.04). One is related to changes in the udev dynamic device management system, and the other is related to the libusb library used to communicate with devices connected via USB.The ISE 14.7 distribution provides an installation procedure "setup_pcbusb" that is intended to configure udev. Unfortunately, it does not work for recent versions of Ubuntu and other Linux systems. Rather than deal with this mess, I suggest setting it up manually.
1. Install the fxload package. This is used to download firmware into the Xilinx Platform Cable USB pod:sudo apt install fxload
2. Next, copy the firmware from the Xilinx installation directory to /usr/share:
sudo cp /opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/*.hex /usr/share
Note: A previous version of this post gave the wrong source directory, which may result in fxload failing to load the firmware. Using the firmware from the correct directory should fix this issue.
3. Create the udev rules file by copying the following text into /etc/udev/rules.d/xusbdfwu.rules. This is needed because the rules file provided by ISE doesn't work with more recent versions of udev:
# version 0003
ATTR{idVendor}=="03fd", ATTR{idProduct}=="0008", MODE="666"
ACTION=="add", ATTR{idVendor}=="03fd", ATTR{idProduct}=="0007", RUN+="/sbin/fxload -v -t fx2 -I /usr/share/xusbdfwu.hex -D $tempnode"
ACTION=="add", ATTR{idVendor}=="03fd", ATTR{idProduct}=="0009", RUN+="/sbin/fxload -v -t fx2 -I /usr/share/xusb_xup.hex -D $tempnode"
ACTION=="add", ATTR{idVendor}=="03fd", ATTR{idProduct}=="000d", RUN+="/sbin/fxload -v -t fx2 -I /usr/share/xusb_emb.hex -D $tempnode"
ACTION=="add", ATTR{idVendor}=="03fd", ATTR{idProduct}=="000f", RUN+="/sbin/fxload -v -t fx2 -I /usr/share/xusb_xlp.hex -D $tempnode"
ACTION=="add", ATTR{idVendor}=="03fd", ATTR{idProduct}=="0013", RUN+="/sbin/fxload -v -t fx2 -I /usr/share/xusb_xp2.hex -D $tempnode"
ACTION=="add", ATTR{idVendor}=="03fd", ATTR{idProduct}=="0015", RUN+="/sbin/fxload -v -t fx2 -I /usr/share/xusb_xse.hex -D $tempnode"
The version of iMPACT provided by ISE 14.7 wants to use libusb version 0.1 rather than the current 1.0 version. This is available in the 20.04 repo. Unfortunately, iMPACT wants to access it by a file name which doesn't end up in the file system. In prior Ubuntu releases, installing the libusb-dev package would create the appropriate symlink, but the latest packaging creates what appears to be a linker text file instead. So we must create the symlink ourselves.
1. Install the libusb-0.1-4 package:
sudo apt install libusb-0.1-4
2. Provide a symbolic link to libusb-0.1.so.4:
ln -s /lib/x86_64-linux-gnu/libusb-0.1.so.4 \
/opt/Xilinx/14.7/ISE_DS/common/lib/lin64/libusb.so
This should be sufficient to let iMPACT run on an Ubuntu 20.04 system. Let me know if it doesn't work for you.
Ok, let's be honest: XST error reporting stinks like week old roadkill.
To break the stalemate on clock distribution in my discrete component recreation of the i4004 CPU, I decided the first step would be to take a hard look at the rise-time of the clock signals on the Instruction Pointer board I've already completed. To do this, I need to put together a running system.
A couple of years ago (has it been that long??) I created an MCS-4 Clock using my Spartan-3E Starter reference board. The i4004 emulation could be configured to use either an emulated Instruction Pointer or the physical IP board. However, this was done before I realized what a disaster the transparent latch version was and switched the chip emulation back to using clocked flip-flops, so I knew I'd need to do some tweaking of the top level modules to work with the latest emulation code.
Mostly what was needed was adding back the module ports for the 50 MHz system clock ("sysclk"). However, after doing so I still got synthesis errors from XST complaining that the data bus was driven by multiple outputs. Well, of course it's driven by multiple outputs: it's a bidirectional bus! This worked before; why did I get errors now?
After literally hours and hours of trying this and that, I found Xilinx tech note 14264 that indicated that this error sometimes can result from another net that was not driven and thus tied to ground during synthesis, causing a cascade of unexpected errors. This led me to discover that sysclk wasn't properly wired into one of the emulated chips in the top clock module. Wouldn't it have been better to generate an error for the unconnected input port?
Fixing this resolved the error, but by then it was too late to try it on hardware. Maybe tomorrow I'll have pretty pictures of the clock line rise and fall timing.
I found a lingering transparent latch in the implementation of the Instruction Decoder module, and I replaced it with a clocked flip-flop. I did a double-check of the Verilog sources, and I think that's the last one.
The OpenCores repository has been updated.
Speaking of OpenCores... When I went to update my project, I discovered the site's encryption certificate has expired. And I still haven't gotten a reply to my report of the out-of-date download tarball. I'm not getting a good feeling about the future of the site.
Maybe someone should archive the site?