tag:blogger.com,1999:blog-3699484483535327202024-03-18T12:30:39.672-04:00Insanity 4004Experiments with the world's first microprocessor
<br>and other electronic explorationsUnknownnoreply@blogger.comBlogger325125tag:blogger.com,1999:blog-369948448353532720.post-85659623115958074362024-03-18T01:05:00.007-04:002024-03-18T12:30:04.782-04:00How high and how fast?<p>Most of the circuitry in the 4004 CPU and other MCS-4 family chips uses a MOSFET to actively pull a signal toward Vss, and a "load" to passively pull it back toward Vdd. In the real 4004 CPU, a "load" is a MOSFET with its gate connected to its drain, but designed so it works sort-of like a resistor. In my re-creation, a "load" is a real resistor.<br /></p><p>When I did my initial breadboard tests of bits of circuitry, I used 10K ohm resistors for loads. I chose this value simply because I happened to have a bag of a hundred of 10K ohm axial resistors left over from another project. Given the low input capacitance of the two MOSFET types I am using (9.5pF for the Fairchild FDV301N, and 1.5pF for the NXP BSS83), it seemed a reasonable choice.</p><p>When I began assembling my boards, I worried that 10K loads wouldn't give good rise times. Back when TTL logic was standard it was common to use a 4.7K pull-up resistor on open collector outputs, so I used these instead. I also didn't understand how "bootstrap loads" worked, and thinking this was a rise time issue I used 2.2K resistors for these. This seemed to work pretty well on the Instruction Pointer board, but I had no engineering data to support these choices.<span></span></p><a name='more'></a><p></p><p>Eventually figured out the purpose of a bootstrap load. A normal load in the i4004 is unable pull all the way to Vdd, while a bootstrap load is able to pull a signal much closer to Vdd. I explain this in more detail in my post <a href="https://insanity4004.blogspot.com/2015/11/the-bootstrap-load-mystery-solved.html">The Bootstrap Load mystery solved</a>. Since a real resistor will pull very close to Vdd, I wondered if I could use 4.7K resistors in place of the bootstrap loads, but when I assembled the Scratchpad Register board I went with the same value resistors as with the Instruction Pointer board.</p><p>As I studied the Arithmetic Logic Unit board's schematic I noticed something strange. The ALU's carry prediction circuitry contains four nearly identical sets of logic, one for each of the data bits. The outputs of this circuitry (N0553, N0556 N0559, N0861) are push-pull drivers. Unsurprisingly, the loads pulling up the gates of the high-side drivers for bits 1 and 3 are bootstrap loads (B1871, B1873), as this allows the outputs (N0556, N0861) to pull higher. What struck me as strange is that the equivalent loads for bits 0 and 2 (R1870, R1872) <i>aren't</i> bootstrap loads.</p><p>I haven't figured out the reason for that yet, but I suspect it might be related to how bits 0 and 2 use inverted polarity from bits 1 and 3.</p><p>This got me wondering about my choices for load resistors. Were 4.7K and 2.2K good choices? I now have two boards using these values and both seem to work pretty well. But I still
didn't have any objective measurements to prove these choices as valid
or not. It was time to get some real measurements.</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeRoTAraDscv5bdys0G_rp2jZ-IEs2UNhUfwoT9DxUhDCjnWpMKUA0hBlY9spz-jXG7N971LII08iQ28upEZD0MDQwHENkITT8fxK21IEyplrw4Fr70FfHrdWAA_TonZaMJUR6pRpcVZRyObhHO1f6aOY-lNx9harCxelMgz4eJm2NN0liWR2hpIJ1gppP/s1296/Screenshot_20240317_224922.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="948" data-original-width="1296" height="234" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeRoTAraDscv5bdys0G_rp2jZ-IEs2UNhUfwoT9DxUhDCjnWpMKUA0hBlY9spz-jXG7N971LII08iQ28upEZD0MDQwHENkITT8fxK21IEyplrw4Fr70FfHrdWAA_TonZaMJUR6pRpcVZRyObhHO1f6aOY-lNx9harCxelMgz4eJm2NN0liWR2hpIJ1gppP/w320-h234/Screenshot_20240317_224922.png" width="320" /></a></div>Here's the bit of circuitry I looked at. This is part of the Instruction Pointer logic that controls precharging of the column sense lines. The input to T0430 on the right is driven by CLK1, which is a clean 5V square wave with fast rise and fall times. T0430 inverts this and drives only the gate of T0426.<p></p><p>On my boards both of these are FDV301N, which have a documented typical input capacitance of 9.5 pF, an output capacitance of 6 pF, and a Vgs threshold of 0.85 V. The load, R1862, is a 4.7K ohm, 1% resistor. The track connecting these, N0522, is all of 18 mils (0.46 mm) in length so not a lot of capacitance there. I figured the total capacitance would be under 20 pF, giving a rise time to 3.16V (τ, or 63.2%, of my 5V Vdd) of about 95 ns.<br /></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgB0HBCtS_7lbAhTjFhw4gjqqmezVis9Mt2UxIJFM_CU-mochb3Ih-OX4KlaGocelKYwCTFg8ZCIENPQ03CStovJmYOPSi_YSMFmdomf0u2iM0_iiupz1RM4O9C0U10gtlwsdwLDkKr9Aof0oEAJe_LlzDUzroRCXkWw-qNPBpRCKXN4GszyK3CUmRMFwH-/s640/dda-20240317-173527-00.tiff" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="480" data-original-width="640" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgB0HBCtS_7lbAhTjFhw4gjqqmezVis9Mt2UxIJFM_CU-mochb3Ih-OX4KlaGocelKYwCTFg8ZCIENPQ03CStovJmYOPSi_YSMFmdomf0u2iM0_iiupz1RM4O9C0U10gtlwsdwLDkKr9Aof0oEAJe_LlzDUzroRCXkWw-qNPBpRCKXN4GszyK3CUmRMFwH-/s320/dda-20240317-173527-00.tiff" width="320" /></a></div>I hooked my digital oscilloscope to the gate (red) and drain (blue) of T0430. My 500 MHz passive probes have an 9.5 pF input capacitance, so I expected to measure 140 ns. Instead, I was surprised to see 240ns. That works out to a capacitance of about 51 pF, which is a <i>lot </i>higher than I expected.<p></p><p>I tried the same measurement using one of my 1 GHz active probes on the drain, which add only 1 pF instead of 11 pF. This reduced the rise time somewhat, but it's still about twice the capacitance I estimated.<br /></p><p>This is all probably related to some dynamic characteristic of MOSFETs I don't yet understand. This would not be the first time, and I'm sure it won't be the last.<br /></p><p> In this case neither the slow rise time nor the peak voltage is significant, as T0426 will be solidly on once its gate rises much above 1V, which takes less than 80 ns.</p><p>Of greater interest is what happens when T0412, T0422, and T0426 turn <i>off.</i> The load connected to their drains, B1859, then turns on the DRAM column sense precharge transistors in preparation for a DRAM row read. These 12 precharge transistors have their drains connected to Vdd and sources to the column sense lines, so as their sources rise their Vgs decreases and eventually they turn themselves off. In the real 4004, a bootstrap load is critical here because their gate voltages directly affect the sense line precharge voltages. <br /></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpfu_yMQH4PaUHP9LdpMi6TfLDdUFf4Ts82xs7arsxcJBLsgXbIkvTl2zAfzf2VuGBRuPLWNNyMkYsdjf3rHlLBBcMMo8m07Ad6soIrwGmg-aQWvpo_daMJw_zirHGthnKR0jBHqKBnw2z_iqpMBcVzmSOKVQ97zCzPAFNBDU630C6mx5UJSqC0XXKCjoI/s640/dda-20240317-165459-00.tiff" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="480" data-original-width="640" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpfu_yMQH4PaUHP9LdpMi6TfLDdUFf4Ts82xs7arsxcJBLsgXbIkvTl2zAfzf2VuGBRuPLWNNyMkYsdjf3rHlLBBcMMo8m07Ad6soIrwGmg-aQWvpo_daMJw_zirHGthnKR0jBHqKBnw2z_iqpMBcVzmSOKVQ97zCzPAFNBDU630C6mx5UJSqC0XXKCjoI/s320/dda-20240317-165459-00.tiff" width="320" /></a></div>Here's what that looks like on my IP board, with the red trace connected to the the gate of T1313, the precharge transistor for bit 8 of the IP array. The yellow trace is connected to the bit 8 column sense line using an active probe.<p></p><p>When a DRAM cell is read, the column sense line becomes the inverse of the bit's value. In this instance the previously-read bit in this column was a 1, so the sense line was low before being precharged. When this bit is read it is also a 1, so the sense line is pulled low again.</p><p>In my implementation, B1859 is a 2.2K, 1% resistor. T1313 is a BSS83, with an input capacitance of only 1.5 pF. Adding 12 of these (18 pF) to the three FDV301N output capacitances (another 18 pF), I naively guessed this signal would have a total capacitance of under 40 pF. Subtracting the 'scope probe capacitance, it looks like the actual capacitance is closer to 80 pF. Oops.<br /></p><p>Note here that the gate voltage never reaches Vdd of 5V, barely topping 4.4V even at the end of the 440ns CLK1 pulse. The 4004 datasheet allows the clock pulses to be between 380 and 480 ns, so a shorter clock pulse would lower the peak voltage by maybe 0.1V. </p><p>The BSS83 datasheet unhelpfully gives the Vgs threshold voltage
as a minimum of 0.1V and a maximum of 2.0 volts. (The datasheet for the CaLogic
SST215 Klaus is using states the typical is 1.0V, but retains the same
wide min/max range.) In this configuration, with the substrate at 0V and the source rising to 2.5V, T1313 appears to turn off with a Vgs of 1.9V. Fortunately for me the sense amplifiers (T1145 for this column) are FDV301N with a threshold voltage far below 2.5V; even a BSS83 would work.</p><p>What would have happened if I'd used a 4.7K resistor instead of 2.2K to replace the B1859 bootstrap load? Assuming a circuit capacitance of 80 pF, the math says the peak gate voltage after 440 ns would decrease from 4.6V to 3.4V, a loss of 1.2V. This would reduce the sense line precharge voltage to about 1.5V, which is getting close to the threshold voltage of an FDV301N as the sense amplifier. With a BSS83 as the sense amplifier you'd be below the maximum threshold of 2.0V, though still above the typical 1.0V.</p><p>How about a 10K resistor? The peak gate voltage after 440 ns would be just 2.1V. Allowing for even a 1V Vgs threshold* in the precharge transistors doesn't leave a safe margin for the sense amplifiers to respond. So while 10K probably would have worked as R1862, it would not have worked reliably if at all for B1859.</p><p>Maybe I guessed good resistor values after all? <br /></p><hr width="50%" /><p>*Why am I decreasing the threshold voltage here? In a BSS83 (and SST215), the source is not internally connected to its substrate (also called its "body"). This is essential for using a MOSFET as a transmission gate. However, Federico Faggin explains that the "body effect" causes a MOSFET's threshold voltage to increase proportionally with the square root of the voltage difference between the source and substrate (Vsb). The 2.5V source-substrate difference likely accounts for much of the 1.9V gate-source difference I observed on T1313. With a lower Vgs the source wouldn't rise as high, and the smaller Vsb would also reduce the body effect increase in the threshold voltage.<br /></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-369948448353532720.post-48608830108464568642024-03-15T22:49:00.005-04:002024-03-15T23:57:55.711-04:00Arithmetic Logic Unit board fully routed<p> Here's the Arithmetic Logic Unit board:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfGr-AVbRY7PIfIFQSV1Qn_bmNJdBY3F6tL7fNs6HJNwrS8m1ftzmV6uEa2X1-cm3DkngTRHcLV9TUJaclMkmF5xcc_8jpLiNdf4eVyJK8N5FqyIbTVQfDVt6ao3Jam2tf-bmmj6GPJLATV1vGwCcrrouGe0gxMs72jy2-QPvsG9D_OkcAtp-1zsM2LEkI/s1109/Screenshot_20240315_211428.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="717" data-original-width="1109" height="259" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfGr-AVbRY7PIfIFQSV1Qn_bmNJdBY3F6tL7fNs6HJNwrS8m1ftzmV6uEa2X1-cm3DkngTRHcLV9TUJaclMkmF5xcc_8jpLiNdf4eVyJK8N5FqyIbTVQfDVt6ao3Jam2tf-bmmj6GPJLATV1vGwCcrrouGe0gxMs72jy2-QPvsG9D_OkcAtp-1zsM2LEkI/w400-h259/Screenshot_20240315_211428.png" width="400" /></a></div><p>All nets have been routed, and the design rule checks run without error. <span></span></p><a name='more'></a><p></p><p><table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilt3i1zVjyHxma85TdI1og_kTxHuXYr_jzi4M1tGZ8OZBmHtgyFdbIG65BeccQdyqFTNVh-4T3oLDioidSAyGR-rBmvhbaosWSTeZoAK-eoaXBwBT_jHC5TFwYtxU-iCVbAsm3o9xBG6c2MBa1nPbKCsJLt7OJEaHgZyilxCuz1MKyTq_X7QzPedd6GzS8/s1003/Screenshot_20240315_225838.png" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" data-original-height="652" data-original-width="1003" height="208" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilt3i1zVjyHxma85TdI1og_kTxHuXYr_jzi4M1tGZ8OZBmHtgyFdbIG65BeccQdyqFTNVh-4T3oLDioidSAyGR-rBmvhbaosWSTeZoAK-eoaXBwBT_jHC5TFwYtxU-iCVbAsm3o9xBG6c2MBa1nPbKCsJLt7OJEaHgZyilxCuz1MKyTq_X7QzPedd6GzS8/w320-h208/Screenshot_20240315_225838.png" width="320" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">ALU board bottom layer tracks<br /></td></tr></tbody></table>It's a coincidence that I'm working on the boards in the order of decreasing component count. It's interesting to me that, despite this, the boards have gotten progressively harder to route. As can be seen in the images, the board is fairly densely packed with components. Each of the components on these boards have at least one lead connecting to either power or ground through a via, plus any vias needed to reach the other two signal routing areas, so there are a <i>lot</i> of vias. I tried to place the vias so they lined up to leave routing channels between them but this has not always been practical. This has sometimes made it challenging to get tracks routed from one side of the board to the other side. where there are a lot of them.<br /></p><p><table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghN5Te1gD0aYn_VfSMzhTZTbzMYvhBq9_yganP3xpBJPOS444A95qWPSeVhs9VeXVvDrXhhfUpxi06BWFO1_wUQPTqbRhtzZ_GOw3lKsSvHXsxeWinDBGbhoEUvELTuenmseZ6gc6877zGXVb75G7aTUuemPcazlseE9MOkbGyV5JsrHcFfTxbjJeKwPo3/s1008/Screenshot_20240315_225159.png" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" data-original-height="650" data-original-width="1008" height="206" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghN5Te1gD0aYn_VfSMzhTZTbzMYvhBq9_yganP3xpBJPOS444A95qWPSeVhs9VeXVvDrXhhfUpxi06BWFO1_wUQPTqbRhtzZ_GOw3lKsSvHXsxeWinDBGbhoEUvELTuenmseZ6gc6877zGXVb75G7aTUuemPcazlseE9MOkbGyV5JsrHcFfTxbjJeKwPo3/s320/Screenshot_20240315_225159.png" width="320" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">ALU board inner layer tracks<br /></td></tr></tbody></table>My layout strategy for the ALU (and ID) boards was to use the bottom layer for tracks running east/west, and the inner layer for tracks running north/south. This view of just the inner layer tracks shows that these tracks do a pretty good job of chopping the board up. Although I really doubt there's a need to worry about it, merging the inner layer with the power plane would play havoc with return current paths for the bottom layer signals. <br /></p><p>Since I only have three signal layers, one idea is to stay with a 6-layer stackup but add a second ground plane behind the bottom layer. The power plane then would get moved to the unused inner layer. That way each of the signal layers is adjacent to a ground plane, though with the default JLCPCB stackup the inner signal layer will be much closer to the power plane than a true ground plane. I'm sure I'm overthinking this, but due to manufacturing processes it's a case of "Buy 5 layers and get the 6th layer free!"<br /></p><p>Before I send the ALU and Instruction Decoder boards off for fabrication, I'm going to put some annotations on the top silkscreen layer to make it easier to identify subcircuits and significant signals. If I don't get badly distracted this weekend I expect I'll send them both off early next week. I hope to get them back two weeks after that.<br /></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-369948448353532720.post-13001344899874157342024-03-12T15:44:00.000-04:002024-03-12T15:44:11.944-04:00Instruction Decoder board layout complete<p> Here it is, the (hopefully) final layout of the Instruction Decoder board:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjJmvSbuGWVeU10PeTMcVkmgVWSsyxjcOi6XocKlqedyZbUmj4cEVf2QAwYNVXtVLt0jD3WJICwxiIG_B0M8bso_hBFze4L5p9oEI0sgwshVf4tDQwR6JwTFrs0Ur0Qyx19lHHCKv3VGbG1wGbpcvW3qqhNAEmtapmZZqnJuUdYtc0XWpP63lJ76FSXraE/s1281/Screenshot_20240312_145858.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="830" data-original-width="1281" height="259" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjJmvSbuGWVeU10PeTMcVkmgVWSsyxjcOi6XocKlqedyZbUmj4cEVf2QAwYNVXtVLt0jD3WJICwxiIG_B0M8bso_hBFze4L5p9oEI0sgwshVf4tDQwR6JwTFrs0Ur0Qyx19lHHCKv3VGbG1wGbpcvW3qqhNAEmtapmZZqnJuUdYtc0XWpP63lJ76FSXraE/w400-h259/Screenshot_20240312_145858.png" width="400" /></a></div><br /><p>Like the previous two and several to follow, this board uses stacking connectors to make the connections between it and the other boards that make up the i4004 CPU. Initially I thought all the inter-board connections could be made through the connector on the right, but once I'd split the master schematic into five smaller schematics I realized that this board and the Arithmetic Logic Unit board had so many connections that a second connector was needed. Thus the connector on the left was added to the designs.</p><p>I thought I was done with this board a few days ago, but while checking the connector pinouts against my master spreadsheet of interboard connections I realized there were six that didn't have pin assignments. These nets were fully routed within the board, but didn't connect to pins on a connector. This would have been something easily correctable by adding wires to the board later, but of course it's better to have caught it now.</p><p>There are a few reasons I'm I haven't sent this board to JLCPCB for fabrication. The primary reason is that I can't test this board without the ALU board; my FPGA interface board just doesn't have enough I/Os to be able to connect to all the ID board outputs. So there's little benefit to sending this one out without the ALU. Secondly, the shipping cost for this board alone is the same as for this board and the ALU board together, and ordering them together will save me about $25.</p><p>The only change I might make to this board before ordering is to reduce the layer count from 6 to 4 by merging the interior signal layer into the power distribution layer. The cost difference is only $6, but with resistive pull-ups I don't need a full power plane and it annoys me to have the extra layers.<br /></p><hr width="50%" /><p>What about the ALU board? There are still 60 unrouted nets remaining. A portion of the circuitry is incompletely routed, and I'm not happy with the component arrangement in that portion. I'm thinking it'll probably be sometime next week before it's finished.<br /></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-369948448353532720.post-82208794135531705222024-03-09T15:29:00.002-05:002024-03-09T16:02:15.371-05:00JLCPCB design rules for Eagle<p>A couple of days ago I "finished" routing the Instruction Decoder board. To be sure JLCPCB wouldn't have manufacturing problems, I used the same Eagle design rules file (DRU) I'd used to fabricate the Scratchpad Register board.</p><p>The Scratchpad board's DRU file started with the Eagle DRU file JLCPCB <a href="https://github.com/JLCPCB/jlcpcb-eagle/blob/master/design%20rules/jlcpcb-2layers.dru" rel="nofollow" target="_blank">posted</a> on GitHub for use with 2-layer boards which I modified for the 4-layer stack-up. Since JLCPCB's published <a href="https://jlcpcb.com/capabilities/pcb-capabilities" rel="nofollow" target="_blank">capabilities</a> allow tighter spacing on 4- and 6-layer boards I assumed this would be safe. The Scratchpad board works, but was this a good assumption?</p><a name='more'></a>The Scratchpad board is a 4-layer stack-up, with interior copper layers used as ground and power planes; all the signals routed on the top or bottom layers. The Instruction Decoder board turned out to be much harder to route so I upped the layer count from 4 to 6, with the inner-most two layers used to route signals I couldn't route on the outer two.<p></p><table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOgFQ6YGxbSflhMpikL9JMd2Vc_RIeodc9T1xBhiaws4BaIMfZcInGhmYly-pc2jKuYwD71jszmJdLhfWTVH4MsMMGZHYtDmXYs8xHSXT0SkcvWlAip9c7TE0gCKu9_k65D6p_qo70acjNAXPAkPotYg2Nqcw3IM7Bq47Bq7qwcBNdJBVjuORAySdf1s6f/s2072/Screenshot_20240308_194709.png" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" data-original-height="1338" data-original-width="2072" height="207" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOgFQ6YGxbSflhMpikL9JMd2Vc_RIeodc9T1xBhiaws4BaIMfZcInGhmYly-pc2jKuYwD71jszmJdLhfWTVH4MsMMGZHYtDmXYs8xHSXT0SkcvWlAip9c7TE0gCKu9_k65D6p_qo70acjNAXPAkPotYg2Nqcw3IM7Bq47Bq7qwcBNdJBVjuORAySdf1s6f/s320/Screenshot_20240308_194709.png" width="320" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Interior layer tracks</td><td class="tr-caption" style="text-align: center;"><br /></td></tr></tbody></table><p></p><p>When I finished routing the ID board I realized there weren't that many tracks routed on one of these interior layers and <i>no</i>
tracks on the other. Rather than make a 6-layer board I'm
probably going to merge the interior signal layer with the power plane
layer and go back to a 4-layer stack-up. Using the minimum
track-to-track spacing of 3.5 mil (0.09 mm) between signals and the
power plane pour sounded sketchy, so I decided to take a closer look at
the design rules.<br /></p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZT3Qjf4e8F0Il-C1jmC7BI-rrm6Fbd-Rr2b22ElKT36-atm6qiVZeU_2HvOYZBSaxunLhuzqgeoisfta0fP7Plxuz5H7H8gVpw73-xpcf_kcTJ32f2yxoe3y-xphv9H4SdskfXwvv7a_Wo9_GMrFeTyzT-cFFET0R5qGoyEUPRDvwggz3ASKQujNRv4EG/s189/minimumClearance4.5b848da.jpg" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="125" data-original-width="189" height="125" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZT3Qjf4e8F0Il-C1jmC7BI-rrm6Fbd-Rr2b22ElKT36-atm6qiVZeU_2HvOYZBSaxunLhuzqgeoisfta0fP7Plxuz5H7H8gVpw73-xpcf_kcTJ32f2yxoe3y-xphv9H4SdskfXwvv7a_Wo9_GMrFeTyzT-cFFET0R5qGoyEUPRDvwggz3ASKQujNRv4EG/s1600/minimumClearance4.5b848da.jpg" width="189" /></a>As I compared the design rules in the DRU file I'd downloaded with the information published on JLCPCB's website, I found several discrepancies. The DRU file specified the wire-to-via clearance as 5 mil (0.127 mm) but the website gives this as 0.2 mm (7.87 mil), which is more than half again larger. Changing the wire-to-via clearance in the DRU resulted in about 45 DRC errors, which I addressed with minor changes in routing and via placements.<br /><p></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUow_wVX78u6TLprwK1g7pw7l70zUsnchipp-TFrazhs05LBobzjcoUlBojGmu7SJ-uFPakrVOtfBWeIcOKwYocBq5JhM_J7T3ykK6PBbWV2iDpLYhlPa5FnrWrRAjyA0CcKBWqosDNZ4b_7YIfSuUAvZsd1kOF9zrasXWd9J7IBcfhXSBt39rHUvV6cro/s193/annularRing1.9d82499.jpg" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="149" data-original-width="193" height="149" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUow_wVX78u6TLprwK1g7pw7l70zUsnchipp-TFrazhs05LBobzjcoUlBojGmu7SJ-uFPakrVOtfBWeIcOKwYocBq5JhM_J7T3ykK6PBbWV2iDpLYhlPa5FnrWrRAjyA0CcKBWqosDNZ4b_7YIfSuUAvZsd1kOF9zrasXWd9J7IBcfhXSBt39rHUvV6cro/s1600/annularRing1.9d82499.jpg" width="193" /></a></div>Then I noticed a discrepancy in the via annular ring size. The DRU file specified this as 3 mil (0.076 mm), while the website clearly documents this as 0.13 mm both graphically and in text. Changing this in the DRU file resulted in another dozen DRC errors requiring more layout changes, mostly to vias I'd already moved.<p></p><p>In a high speed digital design I'd be worried about clean signal return
paths that don't cross an interrupted plane in the next layer down.
However, my i4004 re-creation is not even close to "high
speed". The fastest signal fall times are about 30 ns from 90% to 10%.
Rise-times are even slower because of the use of resistive rather than
active pull-ups. Thus I'm not
really seeing the need for an uninterrupted power plane.</p><p>Maybe I'm just being obsessive, which is an occupational habit for a good software engineer where "close enough" is another way of saying "it's broken". I've changed all the feature-to-feature clearances to 8 mil (0.203 mm) and the board passes DRC. As a hobby project I get to make changes like this because it makes me happy.<br /></p><p><br /></p>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-369948448353532720.post-10982040887199295652024-03-07T01:02:00.003-05:002024-03-07T01:15:04.059-05:00The Instruction Decoder PCB<p>When I started my efforts to construct a discrete-component replica of an Intel 4004 CPU in June of 2012, I realized that I was going to have to split the CPU into several parts. This was largely dictated my hobbyist license for the Eagle CAD program, which limited me to placing components within a 160mm x 100mm rectangle (that's 6.3 x 3.9 inches). So I split the CPU into five boards:</p><ul style="text-align: left;"><li>Instruction Pointers</li><li>Scratchpad Registers</li><li>Instruction Decoder <br /></li><li>Arithmetic/Logic Unit</li><li>Timing and Input/Output</li></ul><p>By October 2012 I'd assembled a working Instruction Pointer (IP) board, and tested it using an FPGA to substitute for the remainder of the CPU.<span></span></p><a name='more'></a><p></p><p>The PCB for the IP board was fabricated by Beta LAYOUT GmbH in Germany using their PCB-Pool service. Including shipping, the bare 4-layer PCB with an ENIG (electroless nickel, immersion gold) finish and a single solder stencil cost me just under $200.</p><p>Over the next few months I began laying out the other four PCBs. Due to a combination of real life, work, and other hobby projects, progress on the other boards came to a halt in March of 2016.</p><p>In April of last year I decided it was time to restart work on this project. I finished the layout of the Scratchpad Register PCB in early September and sent it off to JLCPCB for fabrication. This board is identical in size and construction as the IP board, but cost about half what the IP board cost. I also received <i>five</i> of them for that price, though I have no use for the extras.<br /></p><p>I assembled the SP in late September. During the fall I developed and ran some rather in-depth tests of this board, and mated it to the IP board for additional testing.<br /></p><p>Now I've begun finishing the layout of the Instruction Decoder board I started in 2012. Although this board has a fewer components than either the IP or SP boards it's more complicated to route. Large portions of the IP and SP boards are taken up by the rectangular DRAM arrays, which have a simple grid of connections. As a result, in 2016 I'd changed the board from 4 to 6 layers, even though that would (at the time) result in a significant increase in the cost of the board. </p><p>I'm now down to the last 30 airwires (unrouted segments), and none of these pose a challenge. If I could test this board separately I'd ship it off for fabrication next week. Unfortunately, due to limitations in my test jig, I can only test it when mated to the ALU board, and that board isn't fully routed yet either.</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi33rYO3BqAyytLxxK1dtUqi2JiYHPvLBP8o9qz42bDLbMehT3yJP0QVJc3Rhvitf6J-sS0fjO5uFjKMsNJxKFUd9ARC5Vss6cfuCQKgemjl8IpBjI5wWGLobRZsEBn8dYVZkGZ94mnThNbNfT7O_4qizzaelDoDs_Op5TYgxZEGPgAIzJrdBpU7ODRei1q/s200/Screenshot_20240307_004826.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="200" data-original-width="192" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi33rYO3BqAyytLxxK1dtUqi2JiYHPvLBP8o9qz42bDLbMehT3yJP0QVJc3Rhvitf6J-sS0fjO5uFjKMsNJxKFUd9ARC5Vss6cfuCQKgemjl8IpBjI5wWGLobRZsEBn8dYVZkGZ94mnThNbNfT7O_4qizzaelDoDs_Op5TYgxZEGPgAIzJrdBpU7ODRei1q/s1600/Screenshot_20240307_004826.png" width="192" /></a></div>Both the IP and SP boards have a full-sized copper planes the inner layers: ground on layer 2, and power on layer 15 (Eagle numbering). All other signals are routed on the outer two layers (1 and 16 in Eagle numbering). The current 6-layer stackups for the ID and ALU boards keep the power and ground planes as they are, but add two copper layers between the planes (3 and 14 in Eagle numbering) for routing signals.<p></p><p>Six-layer boards are more expensive than 4-layer boards, but by a surprisingly small increment: only $6. And that's $6 for the minimum order of 5 boards, not per board. Still, since I'm only using one of the additional two layers, it seems like I should be able to do it in four layers. As an experiment I merged ID board's interior signal layer with the power plane, and I get no DRC violations and no apparent orphaned islands. I've put off doing this until I finish all the routing, but I may be able to make the ID and ALU boards with four layers after all.<br /></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-369948448353532720.post-80403547671736644342024-03-03T12:45:00.001-05:002024-03-03T12:50:46.145-05:00Rant: Ubuntu RAID checking<p>In addition to a 40-year career as a software engineer specializing in operating systems, I've also managed corporate and personal computer systems. It should be no surprise, then, that my primary home computer system has RAID 1 arrays for several critical file systems.</p><p>Some years ago, while far from home, I wanted to demonstrate the utility of RAID arrays to a client. As I explained the up-time benefits in case of a failure, I logged into this system remotely and displayed the array status. To my surprise I found that one of the drives in the array had failed! The system continued to run, of course, because of the redundancy. This perfectly illustrated my point to my client.<br /></p>RAID arrays need periodic checking to identify any errors that may have developed. For years this was kicked off by a <i>cron</i> job at 1 am local time on the first Sunday of each month. However, apparently with the adoption of <i>systemd</i> a few years ago, the start time changed. It now starts at a <i>random time in the 24 hour period</i> after 1 am.<p></p><p>Today it randomly started at 9:33 am, which was shortly after I sat down at my computer. It's now 12:30 pm, and these checks will run for <i>another two hours</i>. While this is running, applications randomly freeze as they compete for access to the file systems.</p><p><b><i>What brain-dead idiot thought that starting this at a random time on a Sunday was a good idea?</i></b><span></span></p><a name='more'></a><p></p>
<p>I found a discussion on <a href="https://askubuntu.com/questions/1314959/mdadm-raid-5-pairity-check-control-new-behaviors-in-ubuntu-20-04" rel="nofollow" target="_blank">StackExchange</a> that describes how to control this. In summary, use this command to edit the start configuration:</p><p></p><blockquote><span style="font-family: courier;">sudo systemctl edit --full mdcheck_start.timer<br /></span></blockquote>
<p>I changed the check so it fires up at 2 am the first Sunday of the month, and reduced the randomness from 24 hours to 10 minutes:</p><p></p><blockquote><span style="font-family: courier;">[Timer] <br />#OnCalendar=Sun *-*-1..7 1:00:00 <br />#RandomizedDelaySec=24h <br />OnCalendar=Sun *-*-1..7 2:00:00 <br />RandomizedDelaySec=10m<br /></span></blockquote>
<p>If the check runs for more than 6 hours it will stop and be continued later. The default is to restart the next day between midnight and noon. Again, this is stupid. Can you imagine starting work on a Monday morning, only for your computer to become nearly useless later that morning?</p><p></p>
<p>To change this behavior, use this command:</p><p></p><blockquote><span style="font-family: courier;">sudo systemctl edit --full mdcheck_continue.timer<br /></span></blockquote>
<p>Experience shows my system's checks shouldn't take six hours. But to be thorough, I've changed this to restart the next day at 2 am:</p><p></p><blockquote><span style="font-family: courier;">[Timer]<br />#OnCalendar=daily<br />#RandomizedDelaySec=12h<br />OnCalendar=*-*-* 02:00:00<br />RandomizedDelaySec=10m<br /></span></blockquote><p></p><p>Why have a random start time at all? The idea is that it's bad to have a bunch of activities all fire off at the same time. The randomness spreads out their start times a bit </p>
<hr width="50%" /><p>To forestall the inevitable bleating of "<i>RAID is not backup!!1!</i>", let me assure you I'm well aware of this. When I started my consulting practice 20 years ago, my first client was a company that manufactured RAID controllers. 'Nuf said.<br /></p><p>My use of RAID on this system helps protect against disk failures causing the system to crash and become unusable for an extended period. When (not if) a disk fails, I have the opportunity to replace it without major disruption of my life. Backups, on the other hand, go to a network-attached storage system with a 30TB RAID 5 array, and that gets backed up nightly to off-site storage. <br /></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-369948448353532720.post-275548225683585962024-02-28T16:46:00.002-05:002024-02-29T20:23:10.737-05:00Data bus charge redistribution<p></p><p></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfNsMqNTAvTxxKADZycBfUv80w6faR2HWOkC3Rkqed_qdPaK4b2_e4d8wtMtNARREV18U5V3DRLTgkxOtDCYz_rc9Oc87eedex8n3kdG2sCVmfckdJBrqD4fJaSplnWVWZ9POEEMGNps55WI2zQ8WKXU6tEl-4H-4ZUqC-ClVnmBWf4PbOimjLZdrOSV-s/s1172/Screenshot_20240228_100059.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="1172" data-original-width="819" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfNsMqNTAvTxxKADZycBfUv80w6faR2HWOkC3Rkqed_qdPaK4b2_e4d8wtMtNARREV18U5V3DRLTgkxOtDCYz_rc9Oc87eedex8n3kdG2sCVmfckdJBrqD4fJaSplnWVWZ9POEEMGNps55WI2zQ8WKXU6tEl-4H-4ZUqC-ClVnmBWf4PbOimjLZdrOSV-s/s320/Screenshot_20240228_100059.png" width="224" /></a></div><p>In my previous post I mentioned an anomaly I'd noticed in the data bus state during a period I believed it should be floating but stable.<br /></p><p><a href="https://4004.com/hackaday23/" rel="nofollow" target="_blank">Klaus Scheffler</a> mentioned in his comments that he'd seen the same thing on his board. This got me wondering if I could use the simulator to help me understand this behavior. Sure enough, the sim also shows an indeterminate state on the data bus under similar conditions.<span></span></p><a name='more'></a><p></p><p></p><p>This snapshot of the simulator shows the X12/X22/X32 subcycles of the SUB instruction at address 069, and the A12 subcycle of the instruction at address 06A, in the default test program. Above the data bus we see the subcycle timing signals, while signals below the data bus control access to the data bus in some way. Note that while a "high" state on most of these control signals connect a subcircuit to the data bus through transmission gates, N0676 works the other way: a 0 enables tristate drivers in the I/O buffers to drive the data bus.</p><p>In each of these subcycles, when CLK2 is high N0659 also goes high. N0659 is the signal that pre-charges the data bus to all ones. Between CLK2 going low in X22 and it going high again in X32, the data bus is floating, as indicated by the dotted trace line. However, when CLK1 goes active during X32, D2 and D0 change from a floating high state to an "in-between" or undefined state.</p><p>The only control signal that has gone active during this period is descriptively-named "<span style="font-family: courier;">M12+M22+CLK1~(M11+M12)</span>". This signal gates the data bus to the <i>inputs</i> of both the instruction pointer and scratchpad register subsystems. At first I dismissed this as a cause of the anomaly, this doesn't connect any sort of output driver. They're <i>inputs</i>, right?</p><p></p><table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmTTg_-zgi2DHgvk6qHrs8TLoYDxQNQH7MQFzJ91jMpzrJXLRdwdN78-qDLxx-qS5z713f96G3w4fMZ53njMVAk-Az3j7qeGEZ2uRj47bsgDlgGe2noflGPfbj8FGm_k4_IOks73X80anxwijmMgXexYBdAbTZ3OzXS3q3M7pgE7tBAv7QNLt3qWJpoZY7/s640/dda-20240226-093019-00.tiff" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" data-original-height="480" data-original-width="640" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmTTg_-zgi2DHgvk6qHrs8TLoYDxQNQH7MQFzJ91jMpzrJXLRdwdN78-qDLxx-qS5z713f96G3w4fMZ53njMVAk-Az3j7qeGEZ2uRj47bsgDlgGe2noflGPfbj8FGm_k4_IOks73X80anxwijmMgXexYBdAbTZ3OzXS3q3M7pgE7tBAv7QNLt3qWJpoZY7/s320/dda-20240226-093019-00.tiff" width="320" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Scratchpad board only<br /></td></tr></tbody></table>Remember, though, that the data bus is floating. This means the only thing keeping it at a stable state are the charges stored on the capacitance of the wires and devices wired to them. Connecting one FET gate to the data bus doesn't cause much change in the bus voltage, as there is only a small capacitance to charge from the bus. This image shows what happens when only my Scratchpad Register board is connected. Note the small but perceptible drop in bus voltage during X32/CLK1 as the gate of one FET is added to the load on D0. <p></p><table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEingkdK4TZmQ8FPABPF4gA6_vmr9dqnsr5vEteigI2YSn8Q7_C2T6JDHuYyKkvSRVotR_4XtuvAVI5GNKz7mLL2NGR5K6RHoF3FptQioVQx1F8i7k_dtELUmKFCbKOAejCtkqzR-uzpqtVOXijyGKvh_WtC0_VT98w7tCzpn6WjW5bz0ttdo3rhQUTig-m_/s640/dda-20240226-155010-00.tiff" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" data-original-height="480" data-original-width="640" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEingkdK4TZmQ8FPABPF4gA6_vmr9dqnsr5vEteigI2YSn8Q7_C2T6JDHuYyKkvSRVotR_4XtuvAVI5GNKz7mLL2NGR5K6RHoF3FptQioVQx1F8i7k_dtELUmKFCbKOAejCtkqzR-uzpqtVOXijyGKvh_WtC0_VT98w7tCzpn6WjW5bz0ttdo3rhQUTig-m_/s320/dda-20240226-155010-00.tiff" width="320" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">SP and IP boards<br /></td></tr></tbody></table>I expected the Instruction Pointer circuit to be similar. And it would be, if not for the IP incrementer. The incrementer is the circuit that increments the instruction pointer as the instruction address is output during subcycles A1/A2/A3. This circuit adds more loads to the data bus lines. In the case of D3, "<span style="font-family: courier;">M12+M22+CLK1~(M11+M12)</span>" going high adds one FET gate for the Scratchpad and three for the Instruction Pointer, for a total of four. However, In the case of D0, this adds <i>seven</i> FET gates: one for the Scratchpad and <i>six</i> for the Instruction Pointer.<br /><p>Now the explanation becomes clear. When the inputs to the Instruction Pointer and Scratchpad boards are enabled, the charges must equalize. If the two sides of the transmission gate are at the same level, nothing much happens. But if they're different the charge on the bus flows through the transmission gate until they equalize. In this case, they equalized at just under 2V.</p><p>So is this a problem? No. This is an acceptable behavior because nothing cares what the state of the data bus is during this period.</p><p>I have to say I'm impressed that the simulator even recognizes and correctly displays this situation. Kudos again to Lajos Kintli!<br /></p><p></p><p></p>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-369948448353532720.post-76736243336446089212024-02-26T20:02:00.005-05:002024-02-27T00:28:50.360-05:00Internal data bus pre-charging<p>I "discovered" an interesting feature in the i4004 internal data bus management this weekend. Maybe the rest of you already discovered this, but it's new to me.<br /></p><p>With the Scrachpad Register board working with my test program, I decided to mate it with the <a href="https://insanity4004.blogspot.com/2012/09/like-phoenix.html">Instruction Pointer board</a> I built in 2012. One of my goals was to see if the CLK1 and CLK2 circuits would ring, or if the rise and fall times are slow enough to avoid problems. To my great relief, I see no significant undershoot or overshoot on these circuits, and no ringing at all. Whew!</p><p>However, my logic analyzer showed some suspicious timing on the internal data bus. At first it wasn't clear to me what was happening, so I probed around a bit with my oscilloscope. As I was making notes of my observations I realized what was happening, and this also explained a bit of circuitry in the original chip I didn't previously understand.</p><a name='more'></a>Since there are many connections to the internal data bus, circuits that drive the bus see a significant capacitive load. Although all the internal data bus drivers have active pull-downs (transistors that, when turned on, will pull the circuit to ground), few have active pull-ups (I counted four). The rest only have passive pull-ups (resistors that pull the circuit to Vdd). This means that 1->0 transitions will be fast, but 0->1 transitions will be slower.<p></p><p>How much slower? With my logic analyzer sampling every 20ns, I saw some transitions that took as long as 500ns between entering the instruction phase when the data read begins and the output rising to 1.7V (my configured Vih threshold). That's far too long for reliable operation. So how does the real i4004 handle this?</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgA67-tTWKti-XVGBxS4LqeXH2j_RJnxUpbwNQZAHlYcHjfSCBwlGwlqiBkDaSkKQQBCYsY8MhBt53jW4HkhwBQ8EThNxs22IDttLfCn0dsfKj6pUJGedELTQvRMgTEfwPc4f3k46XOSIWl5YurZxAaBlkxOKOBcDjO5TObp7FWQwqMz2EtRKwmNBY66r-Z/s635/i4004_IO_driver_highlighter.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="472" data-original-width="635" height="238" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgA67-tTWKti-XVGBxS4LqeXH2j_RJnxUpbwNQZAHlYcHjfSCBwlGwlqiBkDaSkKQQBCYsY8MhBt53jW4HkhwBQ8EThNxs22IDttLfCn0dsfKj6pUJGedELTQvRMgTEfwPc4f3k46XOSIWl5YurZxAaBlkxOKOBcDjO5TObp7FWQwqMz2EtRKwmNBY66r-Z/s320/i4004_IO_driver_highlighter.png" width="320" /></a></div><p>This picture shows the schematic for the Input/Output Buffer circuit in the i4004. It's a bidirectional buffer that passes data between bit 0 of the internal data bus and the external D0 pin. There are three more such circuits just like it, one for each of the other data bus bits.</p><p>See the transistor I've highlighted? When I first looked at the i4004 schematic many years ago, I didn't understand why these transistors were there. They're obviously intended to pull the internal data bus to Vdd at some point, but why would this be needed? I/O Buffer has a tri-state push-pull driver right below it, so it's not used to drive inbound data onto the internal bus.<br /></p><p>The answer is that it really is not part of the I/O Buffer at all; it is not involved in moving data either into or out of the i4004. Its function is to pre-charge the internal data bus to Vdd (a "1" state) before internal bus drivers are activated. This makes <i>all</i> bus transitions 1->0 (fast) or 1->1 (really fast), even those with passive pull-ups.<br /></p><p>So what was wrong with my test setup? Because I'm testing only the Scratchpad board (and now the Instruction pointer board) I didn't include any of the I/O buffer functionality in my test setup. Without pre-charging the data bus, 0->1 transitions took forever. The fix was simple: the FPGA now drives ones onto the bus when these transistors would have been on. This eliminated most of my timing issues.</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiDX1AyrB9YNIAjq1IxTu6_KKcmvNNYPMtc0W9VglYK3egtirY_ky_hyQwk5lVE5qovRExEC9aR7x6K1X2QD56-Z02YUFwVAtvTYpNrDu6jvXtYW_xVZDc5NPQ44XoDUXiYFUU7kE-93LJXLmJqsqhKM9vKmwRYan3w653w5gbZgGdMSFenPAi8wQhhX4g/s640/dda-20240226-155010-00.tiff" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="480" data-original-width="640" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiDX1AyrB9YNIAjq1IxTu6_KKcmvNNYPMtc0W9VglYK3egtirY_ky_hyQwk5lVE5qovRExEC9aR7x6K1X2QD56-Z02YUFwVAtvTYpNrDu6jvXtYW_xVZDc5NPQ44XoDUXiYFUU7kE-93LJXLmJqsqhKM9vKmwRYan3w653w5gbZgGdMSFenPAi8wQhhX4g/s320/dda-20240226-155010-00.tiff" width="320" /></a></div>I still have a few anomalies to look at. In this 'scope screenshot, the yellow trace is CLK1, the red trace is CLK2, and the blue trace is X32.<p></p><p>The green trace is bit 0 of the internal data bus during the execution of an LD instruction. The bus pre-charge occurs in subcycles X12/X22/X32 during CLK2, but when CLK1 goes active in X32 180ns later the bit gets pulled down to just under 2.0V. I think the bus should be floating at this point, so why isn't it staying at its pre-charged voltage? Oddly, the LD instruction is not part of the test program that comes with the emulator, so I need to write my own program.<br /></p><p>Separately, while the data bus transitions are pretty fast when driven by the Scratchpad Register board, there seems to be some jitter in the data being output by the Instruction Pointer board. It settles down fairly quickly, but I want to understand why it's happening.<br /><br /></p>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-369948448353532720.post-54968312484600728032024-02-21T19:16:00.006-05:002024-02-22T12:49:03.977-05:00The Scratchpad DRAM tests found a problem!<p>My DRAM test found an actual problem on the Scratchpad Register board!</p><p>Should I be excited that my test performed its function, or sad that there was a problem with the board?</p><p>The test is designed to work in concert with my logic analyzer. A PicoBlaze program implements the March C DRAM test, reading and writing the scratchpad registers repeatedly. If it detects that the data returned from a register isn't the expected value, it pulses an output. This pulse triggers the logic analyzer to log and display the signals it's been recording, which shows me what's been going into and out of the board for the last 25 i4004 instruction cycles. I'd tested this test setup in simulation, using the Verilog Scratchpad board emulation in
place of the actual board, so I had some confidence that the test itself
wasn't broken. But this was the first time I'd connected it to the real board.<br /></p><p>What I saw was the error pulse indicating an error for essentially every attempt to read a scratchpad register. Looking more closely, I saw that the signalling going into the Scratchpad board looked correct, but the data being read was always 1111.</p><a name='more'></a><p></p><p>At this point, let's review the operation of a DRAM cell: <br /></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg52LPidQyEGfJ1Wj-P7pLspss1oKLc4_u47X6qEFIWerIGoIezi1_TcHThda68l5U5qAFn3A8a862lBZ8mncZIVsvac30iCQjQnsqCCrlFxlLvYSvFnF1qMwvXHw3JFFrzY9yGCSFTRcaHBNWd2dqofZnC8JTEdaMlU8DFk_wzIBBsITVx2TSBSGRQJ8ce/s551/DRAM%20Cell.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="551" data-original-width="384" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg52LPidQyEGfJ1Wj-P7pLspss1oKLc4_u47X6qEFIWerIGoIezi1_TcHThda68l5U5qAFn3A8a862lBZ8mncZIVsvac30iCQjQnsqCCrlFxlLvYSvFnF1qMwvXHw3JFFrzY9yGCSFTRcaHBNWd2dqofZnC8JTEdaMlU8DFk_wzIBBsITVx2TSBSGRQJ8ce/s320/DRAM%20Cell.png" width="223" /></a></div>To write a DRAM cell:<p></p><ol style="text-align: left;"><li>The "Data In" line is driven to the desired state (high or low).</li><li>The "Row Write" line is asserted. This allows the signal on the "Data In" line to charge or discharge the storage capacitor to the desired state.<br /></li><li>The "Row Write line is de-asserted. This captures the desired state in the cell. <br /></li></ol><p>To read the DRAM cell:</p><ol style="text-align: left;"><li>The "Data Out" line is precharged to a high state, then left floating.<br /></li><li>The "Row Read" line is asserted. If the storage capacitor is charged, the "Data Out" line will be pulled low. Conversely, if the storage capacitor is discharged, the "Data Out" line will remain charged.</li><li>The sense amplifier (not shown) inverts the state of the "Data Out" line.<br /></li></ol><p>Reading a one from every DRAM cell sounded like a problem in the decoding logic, rather than a failure of an individual cell, row, or column. I fired up my oscilloscope and probed a few key circuits, but everything seemed to be operating properly. One of these I looked at closely was the circuit that activates the column sense ("Data Out") precharge transistors. If this wasn't working the column sense lines would never get charged, and since the column sense amplifiers invert their inputs, all the data would be read as ones.<br /></p><p>The precharge circuit seemed to be pulsing at the appropriate times, but when I probed a column sense line I saw that it didn't charge to the level I expected. Then, when the precharge transistor turned off, the column sense line exhibited an RC discharge curve. This was the same for all the column sense lines I checked. This got me looking at my board design.</p><p>One of my concerns had been that the intrinsic and stray capacitances that this type of circuit depends on would be <i>too small</i>. For example, the FDV301N transistor I'd chosen as the storage element in the DRAM cells has an input capacitance of only 9.5 pF. Thus I'd made provisions for an 0603 sized capacitor in parallel with each storage element to allow me to add capacitance if it was needed, even though I didn't plan to install these (and haven't).<br /></p><p>Another place that charges get stored are the column sense lines. Thus, I'd made provision for the addition of capacitors there as well. When I looked at the board, I found I'd installed <i>4.7K resistors</i> to ground on all the column sense lines. Oops. That accounted for the RC discharge curves and the constant one outputs.</p><p>I disconnected the Scratchpad Register board from the test jig and took it to my soldering bench. The hot air tool made quick work of removing the erroneous resistors. Plugging the board back into my test jig I restarted the test. It's been running the entire time I've been writing this blog entry (over an hour) with nary an error detected.<br /></p>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-369948448353532720.post-1954606295856012072024-02-19T20:28:00.001-05:002024-02-21T10:27:41.835-05:00DRAM testing methodologies<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoJ22ZENTuElPE2-DOdGCMvHrTJdUIbkuBqil4SUqsDXtPTaGbtfZa9uAgDZI0cEnSfTxs9GZ5Rj59as4S0FCzRgvK_EFhU1FW5S9htz1BRqVVeKcV3An1gF-EFnVhyS9QR4SLDCBFutBqsoyO0XF6GqcpJm_Pvd-kag10WKJwLUgrVVB6h9qjE8hYapYc/s876/DRAM%20Architecture.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="707" data-original-width="876" height="161" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoJ22ZENTuElPE2-DOdGCMvHrTJdUIbkuBqil4SUqsDXtPTaGbtfZa9uAgDZI0cEnSfTxs9GZ5Rj59as4S0FCzRgvK_EFhU1FW5S9htz1BRqVVeKcV3An1gF-EFnVhyS9QR4SLDCBFutBqsoyO0XF6GqcpJm_Pvd-kag10WKJwLUgrVVB6h9qjE8hYapYc/w200-h161/DRAM%20Architecture.png" width="200" /></a></div>Since I decided to do proper testing of my Scratchpad Register board, I thought I ought to invest some time in understanding the type of faults a DRAM array might have, and how to test for them. Given that the array on this board is only 8 rows of 8 bits I'm not really concerned with run-time, but I do want the tests to be thorough.<br /><p></p><p>In my search for useful algorithms I came across this series of videos by <a href="https://www.youtube.com/@user-eh5jq3wk2w" rel="nofollow" target="_blank">Professor James CM Li</a> of the <a href="https://www.ntu.edu.tw/english/" rel="nofollow" target="_blank">National Taiwan University</a>:</p><ul><li><a href="https://www.youtube.com/watch?v=EZX95b2GobY" rel="nofollow" target="_blank">16 1 MemTest Intro (32:25)</a></li><li><a href="https://www.youtube.com/watch?v=8zvyQWjLV4U" rel="nofollow" target="_blank">16 2 Memory Test - Classical algorithms (23:41)</a></li><li><a href="https://www.youtube.com/watch?v=ZqRibDsyPyw" rel="nofollow" target="_blank">16 3 MemTest March (25:18)</a></li></ul><p>These are part of a much longer online course (94 videos) on VLSI Testing, but these three address testing RAM. The total run time for all three is only 1 hour 21 minutes. Professor Li speaks English with a pronounced accent, but his pace and careful enunciation make him easy to understand (unlike several videos by others I tried to watch).</p><p>I think I caught one small error in his explanation of the answer to one of his "quizes", but otherwise the content seems solid and is explained well.<span></span></p><a name='more'></a><p></p><hr width="50%" /><p>DRAM tests look for three classes of faults:</p><ul style="text-align: left;"><li>Address Decoder faults</li><li>Memory Cell faults</li><li>Dynamic faults</li></ul><p>A good test algorithm will detect all of the first two classes, and may detect some of the third. <br /></p><p>The most common DRAM testing algorithms march through the array, testing each bit to make sure it can be set to zero and one, reads back with the proper value, and isn't affected by operations on other bits in the array. These algorithms are referred to as March algorithms.<br /></p><p>Initially, I'm planning to implement the "March C-" algorithm:</p><ol style="text-align: left;"><li>Write zeros to all bits in the array.</li><li>For each bit in ascending address order: read the bit and verify it's a zero; write the bit as a one.</li><li>For each bit in ascending address order: read the bit and verify it's a one; write the bit as a zero.</li><li>For each bit in descending address order: read the bit and verify it's a zero; write the bit as a one.</li><li>For each bit in descending address order: read the bit and verify it's a one; write the bit as a zero.</li><li>Read every bit (order irrelevant) and verify it's a zero.</li></ol><p>The initial zeroing of the array will (should?) be accomplished by the eight instruction cycles executed with POC (power-on clear) asserted. The read/write sequence can be executed through the signalling generated by the i4004's XCH instruction. This instruction causes the selected scratchpad register to be read during subcycle X22, and written during subcycle X32. The final read can be done using the LD instruction, which is basically the same as the XCH instruction without the write during subcycle X32.<br /></p><p>Later I'll add tests that read and write register pairs by emulating the SRC (or JIN) instructions to read register pairs, and FIM instructions for to write register pairs.</p><p>Dynamic faults are sensitivities to timing or repetitions. For example, there is normally a refresh cycle during the A22/A32/M12 subcycles for each instruction. Thus, a Scratchpad register is normally refreshed every 8 instructions. However, refresh cycles are suppressed during the second instruction cycle of a double-cycle instruction. If a series of double-cycle instructions are executed, the normal refresh frequency could be cut in half.<br /></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-369948448353532720.post-47927051279494831452024-02-04T13:57:00.003-05:002024-02-04T13:57:27.443-05:00Scratchpad Register board signalling<p>One of the prerequisites for testing my Scratchpad Register Array board is to get a clear picture of the signalling necessary to make it function outside of the rest of the i4004 CPU's circuitry.</p><p>Years ago I split the i4004 CPU into functional chunks, each of which would become a separate PC board. In doing so I tried to keep related circuitry together to minimize the inter-board signalling. Thus the Scratchpad Register board includes many subcircuits:</p><ul style="text-align: left;"><li>8-row x 8-bit DRAM array</li><li>3-to-8 row decoder<br /></li><li>3-bit row refresh counter</li><li>3-bit address latch</li><li>3-bit 2:1 address multiplexer</li><li>4-bit 2:1 data output multiplexer</li><li>4-bit 1:2 data input demultiplexer</li><li>Miscellaneous state decode logic<br /></li></ul><p>The inclusion of these subcircuits means the interface to the board is somewhat more complicated than it would be with direct access to the DRAM address and data signals.</p><p>To read and write the Scratchpad DRAM array, I need to emulate the execution of one of the i4004's
instructions. The only instruction which allows a single Scratchpad
register to be written is "XCH", which exchanges the contents of the
accumulator and the specified register. <br /></p><p><span></span></p><a name='more'></a><p>I have a spreadsheet which I use to track what signals appear on which pins of the inter-board connectors. This spreadsheet also identifies which board sources each inter-board signal, and which boards make use of each signal. From this I extracted only the signals used by the Scratchpad board and started a new spreadsheet with columns for each of the execution phases.</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1KsolJVWrrPYNNNU0OWBBocmqiHlpKfR4-1V41o70Awqrxbam0qC2eDyLbn8oGZBcpMMFfAURcrJ9hyphenhyphen_GYQmohn6NIalD2g23Dtdg0QPFeFk8_uRnDsDqbFmt_69C_odYwUEB8Gn__QM-jeoIAxx6sPqSmRAYztJtOc57MPAE56rHUZlruJ76dTPGPN-Z/s1550/XCH%20R5%20Cycle%20Map.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1086" data-original-width="1550" height="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1KsolJVWrrPYNNNU0OWBBocmqiHlpKfR4-1V41o70Awqrxbam0qC2eDyLbn8oGZBcpMMFfAURcrJ9hyphenhyphen_GYQmohn6NIalD2g23Dtdg0QPFeFk8_uRnDsDqbFmt_69C_odYwUEB8Gn__QM-jeoIAxx6sPqSmRAYztJtOc57MPAE56rHUZlruJ76dTPGPN-Z/w400-h280/XCH%20R5%20Cycle%20Map.png" width="400" /></a></div><p>These inter-board signals make up rows 2 through 21. To these I added the signals local to the SP board that control the DRAM array (rows 26-32 and 34-36), which I'd determined by analyzing the circuitry. By stepping through the execution of an "XCH R5" instruction (located at address 0x062 in the 400x simulator's sample program) I was able to chart out which signals are active during which phases of execution and what they do.</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNd0cYRKoxMrcWy3s7cUBY2tZ7M9xWWuNHQ0ckeMBphW2snnhs3HD47wREQ73SfMQrC1xFGwPUEgO51UCQUUaBKjn1pTrs0fIwNOTerdwj0gG4nVl9umfx40c_3LmuD0ejKXGpnCXHgpVAcvtZiY-E_Vvlmvb9NIt2A_BqA3SkaqC3Rny1DVNxCDT_9tHx/s1314/XCH%20R5%20Cycle%20Graph.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1047" data-original-width="1314" height="319" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNd0cYRKoxMrcWy3s7cUBY2tZ7M9xWWuNHQ0ckeMBphW2snnhs3HD47wREQ73SfMQrC1xFGwPUEgO51UCQUUaBKjn1pTrs0fIwNOTerdwj0gG4nVl9umfx40c_3LmuD0ejKXGpnCXHgpVAcvtZiY-E_Vvlmvb9NIt2A_BqA3SkaqC3Rny1DVNxCDT_9tHx/w400-h319/XCH%20R5%20Cycle%20Graph.png" width="400" /></a></div><p></p><p>Why bother with a spreadsheet when the simulator shows this graphically? Two of the few deficiencies I've found in the otherwise superb 400x simulator is the lack of vertical grid lines or markers in the signal graph, and the ability to save a display configuration. The spreadsheet is persistent, makes it easier to find the signals of interest, and can also be annotated to explain the purpose of otherwise non-intuitive signal names like "<span style="font-family: courier;">(~POC)&CLK2&SC(A32+X12)</span>".</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-369948448353532720.post-3223531218455744412023-10-28T11:02:00.006-04:002023-10-28T11:19:06.217-04:00Yet another digital clock<p><br />The classic *nix first program is one that prints "Hello world" on the console. For me, my first project seems to be a digital clock. I made one when I started experimenting with Microchip PICs in 1999. A few years back I made one using my Verilog emulation of an Intel 4004, So it made sense to make one as my first project using the PicoBlaze soft processor.</p><p></p><div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.blogger.com/video.g?token=AD6v5dxj4mCTGciZqx3nlgwZN3rW5IJ209suVhhddv9gzUJIalW_zzOE0XkkSC5Z5cyLi1OtK1PG8pCFz2nSil36yw' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div><p></p><p>After recording this video I left it running overnight. The next morning, to my consternation, I found it had stopped with the display showing. 11:01:12.</p><p><span></span></p><a name='more'></a>My first thought was maybe there had been a power glitch or something that had caused the FPGA to reset, but the LCD had retained its contents. However, the 8 LEDs to the right of the LCD were still counting. These are driven from a simple Verilog counter that increments in response to the pulse-per-second "tick" signal that is also read by the PicoBlaze for timekeeping. That told me the FPGA was still loaded and working.<p></p><p>Maybe the LCD controller was wedged somehow? I've never seen one do this, but the state machines I'm using to drive the LCD interface beat on it basically at maximum speed. To check I used an oscilloscope to probe the LCD's I/O pins, but none of the signals were changing.<br /></p><p>My next thought was maybe the PicoBlaze core was crippleware. Some FPGA tool vendors intentionally generate self-terminating logic when using their freeware tools to prevent their use for anything but brief experiments. Xilinx is not known for this (and I would not use any vendor's products that did) but maybe the PicoBlaze core was an exception?</p><p>Normally my next step would be to export a bunch of signals to the expansion port and use my Intronix LogicPort logic analyzer to observe the internal operations. However, the LogicPort is currently wired to my i4004 test board, and I really didn't want to have to rewire it later.</p><p>I've often wondered about using ChipScope, Xilinx's debugging tool. I'd looked into using this long ago, but it appeared to require a rather expensive license. Yet I'd seen recent discussions on using it with the WebPack (freeware) license. I found an old MIT lab exercise on using ChipScope and attempted to follow the procedure. When I tried to generate the ChipScope cores using Coregen, it refused for lack of a proper license.</p><p>Checking my Xilinx licenses I discovered that my WebPack license was for ISE 12.3. Logging on to the AMD website (they recently acquired Xilinx) I generated a new WebPack license for 14.7 and loaded it. I ran into a few snags along the way (see my previous post <a href="https://insanity4004.blogspot.com/2023/10/running-xilinx-chipscope-under-ubuntu.html">Running Xilinx ChipScope under Ubuntu</a>) but eventually I got my cores generated and the ChipScope analyzer running.</p><p>I really wasn't looking forward to debugging a problem that only showed up after 11 hours of runtime. I've done that and it isn't fun at all. My first attempt at speeding this was to shorten the 1 second clock "tick" period. I knew from simulations that the clock's LCD update would only take about 400 microseconds -- at least that's what it took using my simulated LCD controller which uses delays taken from the datasheet. Changing the tick period to 1 millisecond proved to work with the real LCD, and I was excited when the clock halted after about 40 seconds, again showing 11:01:12.</p><p>My first ChipScope probe monitored the PicoBlaze's program counter. If the PicoBlaze had self-terminated, this would have stopped updating. I was happy to find it was still stepping through my code, polling the LCD output status waiting for it to go idle. Yet other ChipScope probes showed the output FIFO was empty and the two FSMs were idle. Finally, I added the PicoBlaze I/O port interfaces to the probe monitoring the program counter. This revealed my error.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUP1nHRDoV90KWvE7l4_mKI_N6osYgPL4T9EB5CXd_GJn57yEYkuYHiKs-mf6kehpyw-Y7Qi9O0uMsceuyXLNYGF4DWfeIP8-KXi7VO8gIYpi0qzO7mSNa9Via4PjfuWeUhUVmZWk_dmldxBNGJt3pV0LTf1r2tklo3Lk0akLWt-c3RWfKy3-ELBAiqGaM/s1064/UG129_Fig_6-3.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="649" data-original-width="1064" height="195" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUP1nHRDoV90KWvE7l4_mKI_N6osYgPL4T9EB5CXd_GJn57yEYkuYHiKs-mf6kehpyw-Y7Qi9O0uMsceuyXLNYGF4DWfeIP8-KXi7VO8gIYpi0qzO7mSNa9Via4PjfuWeUhUVmZWk_dmldxBNGJt3pV0LTf1r2tklo3Lk0akLWt-c3RWfKy3-ELBAiqGaM/s320/UG129_Fig_6-3.png" width="320" /></a></div><p></p><p>Xilinx user guide UG129 documents the PicoBlaze. Figures 6-1 and 6-3 show the recommended input logic. Figure 6-3 shows the input data being registered both before and after the input multiplexer. I'd split the input port selection into two levels: port_id[7:4] selected which module provided the input data, while port_id[3:0] was passed to the modules to select what data within the module was provided. Thus I had two layers of multiplexer, and I was registering the data after <i>both</i> mux layers. This meant the LCD status was delayed by an extra clock cycle, and arrived at the PicoBlaze <i>after</i> it was sampled by the processor. Removing the clocking from after the first mux fixed the issue.<br /></p><p>I have no idea how this worked in the first place, and even less idea why it always stopped when displaying 11:01:12 and not some other value. But it taught me how to use ChipScope, and that may be very helpful in the future.<br /></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-369948448353532720.post-50369618554894677572023-10-26T20:28:00.001-04:002023-10-26T20:33:38.870-04:00Running Xilinx ChipScope under Ubuntu<p>I've belatedly realized that ChipScope Pro is a free feature of Xilinx ISE 14.7. While trying a simple example I ran into two problems, both of which I have managed to work around.<br /></p><p><span></span></p><a name='more'></a>First, my attempts to create the ChipScope controller and analyzer modules with Coregen failed with errors like:<p></p><p></p><blockquote><span style="font-family: courier;">Failed to generate file: chipscope_bb_lib </span></blockquote>Searching on the Internet I discovered that this can be linked to a problem with the Java JDK provided with the ISE installation. Looking in the ISE installation I found two different Java installations:
<blockquote>
<pre><span style="font-family: courier;">/opt/Xilinx/14.7/ISE_DS/ISE/java
/opt/Xilinx/14.7/ISE_DS/ISE/java6</span></pre></blockquote>
<p>I renamed the directory called "<span style="font-family: courier;">java</span>" to "<span style="font-family: courier;">java5</span>", and created a symlink called "<span style="font-family: courier;">java</span>" to the "<span style="font-family: courier;">java6</span>" directory:</p>
<blockquote>
<pre><span style="font-family: courier;">cd /opt/Xilinx/14.7/ISE_DS/ISE/
mv java java5
ln -s java6 java</span></pre></blockquote>
This allowed Coregen to generate my ChipScope cores. Yay!<p>With my FPGA loaded, I then attempted to start the ChipScope Analyzer from within ISE. This displayed the expected happy messages in the ISE Console window, but nothing else happened. Eventually I found these error messages:
</p><blockquote>
<pre style="overflow: auto;"><span style="font-family: courier;">/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/unwrapped/analyzer: 72: /opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/unwrapped/cs_common.sh: XIL_DIRS[0]=/opt/Xilinx/14.7/ISE_DS/ISE/: not found
/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/unwrapped/analyzer: 73: /opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/unwrapped/cs_common.sh: count++: not found
/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/unwrapped/analyzer: 152: /opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/unwrapped/cs_common.sh: Syntax error: Bad for loop variable</span>
</pre></blockquote>
<p>These I recognized as what happens when a program assumes that the default system shell is "bash" when it's actually "sh" (or "dash", in the case of Ubuntu). This is easy to fix, at the cost of a fractionally slower system startup (dash being a bit faster than bash):
</p><blockquote>
<pre><span style="font-family: courier;">sudo dpkg-reconfigure dash</span></pre></blockquote>
<p>Ta da! Now I can start the ChipScope Analyzer from within ISE.</p><p></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-369948448353532720.post-18028185766754791802023-10-04T16:38:00.000-04:002023-10-04T16:38:01.856-04:00Xilinx firmware download problems<p>I've discovered an error in my post <a href="https://insanity4004.blogspot.com/2022/04/making-xilinx-ise-impact-147-run-on.html">Making Xilinx ISE iMPACT 14.7 run on Ubuntu 20.04</a>. I've corrected the error, and added a note explaining that a previous version contained an error.<br /></p><span><a name='more'></a></span><p>So, what was the error?</p><p>I'm setting up ISE on a new Linux installation (Kubuntu 22.04.3 LTS), and I followed the instructions in the posts in this blog. When I tried to connect to my Digilent Spartan-3E Starter board, iMPACT reported it could not connect.<br /></p>Looking at my syslog file I found the following error:<p><span style="font-family: monospace;"><span style="background-color: white; color: black;"></span></span></p><blockquote><span style="background-color: white; color: black;"> </span><span style="font-size: x-small;"><span style="font-family: courier;">systemd-udevd[434471]: 3-2.1.1.2: Process '/sbin/fxload -v -t fx2 -I /usr/share/xusb_emb.hex -D /dev/bus/usb/003/011' failed with exit code 255.</span></span></blockquote><p></p><p>Running fxload in a terminal window produced this output:</p><p></p><blockquote><span style="font-size: x-small;"><span style="font-family: courier;">$ /sbin/fxload -v -t fx2 -I /usr/share/xusb_emb.hex -D /dev/bus/usb/003/011 <br />microcontroller type: fx2 <br />single stage: load on-chip memory <br />open RAM hexfile image /usr/share/xusb_emb.hex <br />stop CPU <br />can't write 31 bytes external memory at 0x222e <br />unable to download /usr/share/xusb_emb.hex<br /></span></span> </blockquote><span style="font-family: monospace;"></span><p></p><p>Okay, this <i>used</i> to work! What did I do wrong?</p><p>After checking permissions and such, I compared the MD5 checksum of the file I'd copied to /usr/share with the one on a system that works. They were different, so I went looking for the source of the problem.<br /></p><p>Xilinx ISE 14.7 supports quite a few different iMPACT compatible JTAG
pods. Many of these are based on commodity USB interface chips that
require firmware to be downloaded from the host. The ISE installation
for Linux provides firmware files for seven of these chips.</p><p>Searching the ISE installation directory, I found <i>nine</i> directories containing files named "xusb_emb.hex". </p><p>Each of these nine directories contains seven firmware files, one for each of the seven devices. Rather than there being one set of seven firmware files replicated nine
times, there are three distinct sets of files:
one set in four directories, a second set in another four directories,
and a third set in one directory. <br /></p><p>For the Digilent Spartan-3E Starter board, which uses the xusb_emb.hex
file, the firmware from the first or second sets seem to work fine; the
firmware from the remaining set fails to load. </p><p>Not realizing this, it appears I referenced the wrong source directory when specifying the source of the firmware files. Copying the firmware files from one of the other directories results in a successful load and (as best I can tell) proper operation of the JTAG interface.<br /></p><p>I hope this didn't cause too many people trouble. Mea culpa!<br /></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-369948448353532720.post-37610920318491989632023-09-29T10:28:00.003-04:002023-09-29T22:33:57.330-04:00When is impedance matching critical?<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYxbiMtKqc9rzCyqUir_DRouPWu_T9OZ9xsEcKakdf4_0aZbrg6eChwiaPoVpS_T79UX_zzmLMcgROS6QvJvwyTjvxG5fL96oE2-qJLtvjZ0TPcuIMvBxAPjYSmWPa6fOVFn_Heq_qNudcYKelkMdJa6G5Ng1Cq1pGnwFjfI0nnb83j_8tL2Qf3HohujsN/s970/Screenshot_20230929_090133.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="730" data-original-width="970" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYxbiMtKqc9rzCyqUir_DRouPWu_T9OZ9xsEcKakdf4_0aZbrg6eChwiaPoVpS_T79UX_zzmLMcgROS6QvJvwyTjvxG5fL96oE2-qJLtvjZ0TPcuIMvBxAPjYSmWPa6fOVFn_Heq_qNudcYKelkMdJa6G5Ng1Cq1pGnwFjfI0nnb83j_8tL2Qf3HohujsN/s320/Screenshot_20230929_090133.png" width="320" /></a></div><p>One of the questions I asked myself in my previous post was when does it become critical to have a impedance-matched traces? Today I came across an interesting <a href="https://www.jlab.org/accel/eecad/pdf/050rfdesign.pdf" rel="nofollow" target="_blank">presentation</a> by <a href="https://www.linkedin.com/in/rick-hartley-8571216/" rel="nofollow" target="_blank">Rick Hartley</a>, then a Senior Principal Engineer at L-3 Avionics Systems, now Principal Engineer at RHartley Enterprises.</p><p>In his presentation, Rick Hartley states that impedance matching becomes critical when the trace is 1/16th the wavelength of the signal in the propagation material. Here's the relevant slide, giving the formulas.</p><p><span></span></p><a name='more'></a>In my case, I'm working with signals of roughly 2.45 GHz. The PCB material has a stated dielectric constant of 4.4, but at these frequencies I believe the effective dielectric constant may be around 3.91. Cranking these numbers through a calculator gives a signal critical length of 3.87 mm.<p></p><p>With an actual trace length of about 2.54 mm, the trace in question appears to be shorter than the signal critical length. Perhaps it's not an impedance mismatch causing my problems?</p><hr width="75%" /><p>To confirm I'm not using my vector network analyzer improperly — always a risk when using a new piece of equipment — I decided to experiment with some commercial antennas. First I tried connecting my VNA to an air-band (108 to 137 MHz) "rubber ducky" antenna from a handheld transceiver. I figured it would be smart to start at a lower frequency, in case this VNA has a problem at the high end. This test showed a nice dip in the return loss ("LOGMAG" format in the LiteVNA) centered near the middle of the voice communications frequencies. So far, so good.</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpi_LFRp9W0mY8QsIso6y5XcJPk5sYii8tRDwWS-PIzFqD2gLnskthM3Pr8d1MmMSsgb-_4RF8H-AdI2Z8uwkWfJnTdA8C4fPX_AseX_mytnwKKbN91JYdnRM3LUneQuBsQpmlKuowG_xUOPE6_-JAVNQ4IQycdYpgWUXrrZSFuZFdmRVXNwASFQ_7b-C6/s4080/PXL_20230929_210103988.jpg" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="3072" data-original-width="4080" height="151" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpi_LFRp9W0mY8QsIso6y5XcJPk5sYii8tRDwWS-PIzFqD2gLnskthM3Pr8d1MmMSsgb-_4RF8H-AdI2Z8uwkWfJnTdA8C4fPX_AseX_mytnwKKbN91JYdnRM3LUneQuBsQpmlKuowG_xUOPE6_-JAVNQ4IQycdYpgWUXrrZSFuZFdmRVXNwASFQ_7b-C6/w200-h151/PXL_20230929_210103988.jpg" width="200" /></a></div>Next I tried an antenna taken from an old 802.11bg WiFi router. It showed a -35 dB or better return loss near the low end of the 2.40 - 2.50 GHz ISM band, which is what I would expect to see. This suggests that I'm using the VNA correctly. My boards operate in the same ISM frequency band so my tests should be valid.<br /><p></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2cOz4sUgm2iOpghmsNNapOx3BhBTKNzsfx1FFZwsQbCSSyz00_6G_Oudmh91OaWCCjG6GMRejDijQzXI59tPz96hcNBhWJorvLrPWYKH0FWOCmVyft8Vp9EqMBs6AhaN9w1B1U2cGAqL9f-V6D_uhyC3cU7h_IKu7KO4_IXO5BFqqDGoACPEtjehhs0gL/s4080/PXL_20230929_204033496.jpg" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="3072" data-original-width="4080" height="151" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2cOz4sUgm2iOpghmsNNapOx3BhBTKNzsfx1FFZwsQbCSSyz00_6G_Oudmh91OaWCCjG6GMRejDijQzXI59tPz96hcNBhWJorvLrPWYKH0FWOCmVyft8Vp9EqMBs6AhaN9w1B1U2cGAqL9f-V6D_uhyC3cU7h_IKu7KO4_IXO5BFqqDGoACPEtjehhs0gL/w200-h151/PXL_20230929_204033496.jpg" width="200" /></a></div>I have a NanoVNA test board, which is designed to make it easy to experiment with filter circuits. I mounted one of the Johanson 2450AT43A100 chip antennas I used for my boards vertically onto this test board. While not ideal, I hoped this would give a better test result than soldering the end of a cut coax cable to one of my boards. I wouldn't expect a -35 dB return loss, as the chip antenna is only specified to give a -9.5 dB return loss.<p></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEmg58cXiEYRrIecyo7vm8rgPQQMUdF3GepXCKk-ClYR4BulWqC2jC8HF1WowB9F-L-Yibp0-M8gZ-Fxr9PEIcthxHQOZYLjSygxxoxpZxkEAAk7oXlePmsFAlazX1VI9WCRE3I7qSUVyqmbBo4xSXmhuiazU41ivinIg53voPQU-Y0WC0ZhFdukOacHAA/s4080/PXL_20230929_210928124.jpg" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="3072" data-original-width="4080" height="151" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEmg58cXiEYRrIecyo7vm8rgPQQMUdF3GepXCKk-ClYR4BulWqC2jC8HF1WowB9F-L-Yibp0-M8gZ-Fxr9PEIcthxHQOZYLjSygxxoxpZxkEAAk7oXlePmsFAlazX1VI9WCRE3I7qSUVyqmbBo4xSXmhuiazU41ivinIg53voPQU-Y0WC0ZhFdukOacHAA/w200-h151/PXL_20230929_210928124.jpg" width="200" /></a></div>But when I tested it, I saw negligible return loss in the 2.40 - 2.50 GHz ISM band (only 1.42 dB at 2.45 GHz). I had to broaden the scan well above the 2.50 GHz to see any significant return loss: the dip shown peaks at -4.5 dB at about 2.9 GHz.<p></p><p>This antenna is supposed to be naturally tuned to 2.45 GHz when fed with a 50 ohm source. Maybe this odd configuration requires a bit of tuning to get a good match? I'm really a novice at RF, and 2.45 GHz is not an easy place to start.<br /></p><p>Johanson makes (or made) a reference board for this chip, but I can't find anyone who stocks it. I guess the next step is to build some test boards myself using their descriptions.<br /></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-369948448353532720.post-35415576241987299622023-09-26T14:49:00.000-04:002023-09-26T14:49:42.256-04:00Proof I'm not an RF engineer<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLNgTBpOaAClEuO0Z_b6QCW98o8ZHANKpTkdhrifbvdOBUafB8e18qKxgVjaiOOC1zQHIoIp324DOmwY4vzJTD31nVUlHx_ibiGu9JzDBB4wNXQBfIKWY3iTi_yiEneWb3XXCCsVhqiqa05znHuOoE343_VfyKJBmlB4Nxq11kRacC6sZzbgdYuNUYGI3V/s765/Screenshot_20230926_123118.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="765" data-original-width="353" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLNgTBpOaAClEuO0Z_b6QCW98o8ZHANKpTkdhrifbvdOBUafB8e18qKxgVjaiOOC1zQHIoIp324DOmwY4vzJTD31nVUlHx_ibiGu9JzDBB4wNXQBfIKWY3iTi_yiEneWb3XXCCsVhqiqa05znHuOoE343_VfyKJBmlB4Nxq11kRacC6sZzbgdYuNUYGI3V/s320/Screenshot_20230926_123118.png" width="148" /></a></div>Back in 2013 I did a project with a Nordic Semiconductor nRF24LE1 chip. This is an 8051 compatible microprocessor with a built-in 2.4 GHz wireless transceiver. Conscious of how poor my knowledge of RF design is I followed the sample layout of the RF section exactly for the antenna. And by "exactly", I mean I overlaid the sample Gerber file onto my PCB layout and used that to position the components and route tracks. Without the proper tools to tune an inverted-F antenna like on the original, I used a commercial 2.45 GHz chip antenna with a 50 ohm impedance.<p></p><p>Everything seemed to work exactly as designed except the RF section. I could not get the board to talk to a commercial board using the same nRF24LE1 chip. Clearly I'd botched something.</p><p><span></span></p>I called a friend who is an Extra-class amateur radio operator and asked his advice. He reviewed my choice of passive components in the RF section and had me change out a couple which he deemed inappropriate for use at 2.45 GHz. This made them work when talking to each other, but they still wouldn't talk to the commercial boards and had significantly reduced range. Without the test equipment necessary to look at a 2.45 GHz signal, the project got shelved.<p></p><p><span></span></p><a name='more'></a>With the advent of inexpensive spectrum analyzers like the <a href="https://www.tinysa.org/wiki/" rel="nofollow" target="_blank">TinySA</a>, and vector network analyzers like the <a href="https://nanovna.com/" rel="nofollow" target="_blank">NanoVNA</a>, it's now possible for me to dig into this without spending thousands of dollars. There's no practical reason for me to do this, as the original purpose of this project is years past. But I hate unresolved questions.<p></p><p>While I learn to use my new toys... err... tools, I took another look at the board layout. The feed to the antenna is supposed to have a 50 ohm characteristic impedance. This board is 1.0 mm thick FR4, with a solid ground plane on the bottom excluding the area where the chip antenna is mounted. The calculator I used said a microstrip transmission line should have a width of 73 mils (1.85 mm), so that's what I used.</p><p>Now I realize that this configuration isn't a microstrip, it's a coplanar waveguide with a ground plane, which requires a completely different calculation. Plugging in a 73 mil trace and 7 mil spacing to the ground fills on the top, I get about 36 ohm impedance. Oops.</p><p>This seems bad, but the trace is only about 100 mils (2.54 mm) long, a tiny fraction of the 4.8 inch (122 mm) wavelength of this signal. Is this impedance mismatch enough to cause serious problems, or is there something else wrong? Perhaps there are other components in the matching network that are unhappy at 2.45 GHz?</p><p>I think what I'm going to do is build a test board like the one described by the antenna manufacturer in the chip antenna's data sheet. That will let me experiment with my VNA and something that should have known characteristics. This should help me understand if I'm reading the indications correctly.<br /></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-369948448353532720.post-25230228901280868042023-09-24T16:31:00.003-04:002023-09-24T18:38:48.968-04:00Testing... testing?<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijgZgfK0G9ApYhauKAzkeFTplH27kkrStncQjhE1hDnRQdoPk875GRCnzcipGaNr-nTg6Nyu3xesdGle_1YzF5mi7fVVnKG9K5AW_ma-bEanzUjMpWeCLXJcCTK25l3qtdzUTs8AlOuTodXAjkaXUTWLA70SJr5Q_Fl1TR0k97H-BOqtzNypsLEfs3I56d/s300/testing_in_progress.jpeg" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="168" data-original-width="300" height="112" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijgZgfK0G9ApYhauKAzkeFTplH27kkrStncQjhE1hDnRQdoPk875GRCnzcipGaNr-nTg6Nyu3xesdGle_1YzF5mi7fVVnKG9K5AW_ma-bEanzUjMpWeCLXJcCTK25l3qtdzUTs8AlOuTodXAjkaXUTWLA70SJr5Q_Fl1TR0k97H-BOqtzNypsLEfs3I56d/w200-h112/testing_in_progress.jpeg" width="200" /></a></div>In a comment on my last post, Klaus Scheffler asked: <p></p><p></p><blockquote><i>How do you plan to test the register board? I first populated only all
the DRAM cells without column and row selection logic, connected an
Arduino to all column and row lines, and tested the DRAM bit by bit.</i></blockquote><p>That's an excellent question. </p><p></p><a name='more'></a>When I started this project a decade ago, I recognized that just building it and hoping it worked would be a bad idea. This is why I spent a month or so <a href="https://insanity4004.blogspot.com/2012/06/building-dram-cell.html">experimenting</a> with the pieces I expected to have the most trouble with, using individual BSS83 transistors mounted on Surfboard <a href="https://www.capitaladvanced.com/33143.htm" rel="nofollow" target="_blank">Model 33143</a> SMT prototyping adapters, a Microchip <a href="https://www.microchip.com/en-us/product/PIC16F876" rel="nofollow" target="_blank">PIC16LF876</a> microprocessor, and a solderless breadboard. Only once I was reasonably sure the system would work did I consider building an entire CPU.<br /><p></p><p>Once I did decide to build it, the CAD tools I had available forced me to <a href="https://insanity4004.blogspot.com/2012/07/partitioning.html">partition</a> it into multiple boards. I also recognized it was quite probable that something wouldn't work initially, and if I had to respin a board I didn't want it to be a single, large, and expensive board.</p><p><i>But how would I test the boards individually?</i></p><p>This project started out as a means to experiment with FPGAs, and I owned a Spartan-3E reference board. When I started laying out the <a href="https://insanity4004.blogspot.com/2012/07/instruction-pointer-board.html">Instruction Pointer</a> board, I designed it so that it could plug into an <a href="https://insanity4004.blogspot.com/2012/09/creating-test-jig.html">expansion board</a> that mated with my S3E reference board. All the inter-board circuits pass through stacking connectors, and the FPGA has access to all these required for the IP and SP boards. This way, the logic not implemented in hardware could be emulated by the FPGA.<br /></p><p>So, how am I going to test the Scratchpad Register board? I've come up with several possibilities:</p><h4 style="text-align: left;">Option 1: Just try it and see if it works</h4><p style="text-align: left;">This is pretty much what I did with the Instruction Pointer board. I also hooked my logic analyzer to the inter-board circuits and recorded a snapshot. I could do the same, triggering the logic analyzer on one of the six Scratchpad control lines changes state, and a 4004 assembly program exercising the registers.</p><p style="text-align: left;">The downside of this is that it's not a rigorous test by any means, and it might be hard to capture intermittent failures.<br /></p><h4 style="text-align: left;">Option 2: Bit-bang with a PicoBlaze soft microprocessor<br /></h4><p style="text-align: left;">This is roughly equivalent to what Klaus did, only using a PicoBlaze in the FPGA instead of an Arduino. The difference is that I can't directly drive the row and column select lines directly, as there is decode logic in the way. Instead, I'd have to emulate the internal workings of the i4004 CPU when it accesses the Scratchpad registers.</p><p style="text-align: left;">To speed things up I'd probably implement the i4004 instruction cycle in FPGA logic, leaving the PicoBlaze to control the data and the type of access to the Scratchpad.<br /></p><h4 style="text-align: left;">Option 3: Create a microprogrammed testing scaffold</h4><p style="text-align: left;">One of my current interests is in how microprogrammed CPUs operate. Rather than using a PicoBlaze, I thought it might be interesting to implement a microprogrammed test scaffold to exercise the Scratchpad Register board.</p><p style="text-align: left;">This would run the fastest, but would also involve the most coding. Probably not worth the effort, though.<br /></p><h4 style="text-align: left;">Option 4: Parallel execution and comparison<br /></h4><p style="text-align: left;">Since I have the entire i4004 CPU implemented in the FPGA, one attractive option is to run the hardware and the FPGA implementations in parallel with a 4004 assembly program exercising the Scratchpad registers. Writes to the Scratchpad would go to both implementations, while reads would compare the data returned from the hardware with that returned by the FPGA.. The results should be identical, and any differences would indicate a failure in one or the other.</p><p style="text-align: left;">This technique has the added benefit of being extensible to test other boards singly or together without having to implement something completely custom for each test configuration.<br /></p><p style="text-align: left;"><br /></p><p style="text-align: left;">I haven't decided what I'm going to do yet. Option 2 sounds like fun, as I haven't experimented with the PicoBlaze yet, but it may not get beyond a high-level design phase. In the end I'll probably go for Option 4.<br /></p>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-369948448353532720.post-66590015523454908412023-09-23T18:30:00.002-04:002023-10-26T22:55:49.211-04:00Scratchpad board assembled<p>I've finished assembling the Scratchpad Register board. Here it is, in all its glory:<br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGbRZEr4R55NZVl-z9l9e8daoQHj49Ivf6DwLkEEGn8QjLJ0KNQ_Hju_cfmSHjMlUA1ygFT4yL_6GsCHgt2sMlW1sjlD8X05mVDJNsk-8A2Na3I95J6qVsHAzgwHNndnea5Cbt2macKBnFhN_kLFskw4X4-x4OyVS3l63XmB6i2_mzG6QhK2AUlDJrmIt4/s4035/Scratchpad_Board.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="2809" data-original-width="4035" height="279" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGbRZEr4R55NZVl-z9l9e8daoQHj49Ivf6DwLkEEGn8QjLJ0KNQ_Hju_cfmSHjMlUA1ygFT4yL_6GsCHgt2sMlW1sjlD8X05mVDJNsk-8A2Na3I95J6qVsHAzgwHNndnea5Cbt2macKBnFhN_kLFskw4X4-x4OyVS3l63XmB6i2_mzG6QhK2AUlDJrmIt4/w400-h279/Scratchpad_Board.jpg" width="400" /></a></div><p><span></span></p><a name='more'></a><p></p><p>My time estimates were thrown off when I discovered I hadn't gotten the stencil flat against the board when I started working on the left side of the board last night. I'd already populated the entire DRAM array when I realized that the solder paste for the row drivers (the unlabeled column of components extending to the right of the DRAM array itself) was just a smear rather than well-defined rectangles. After considering my options, I ended up wiping off all the solder paste for those components before reflowing the rest of the board. Otherwise I would have finished last night.</p><p>This afternoon I sat down to populate the missing components. The driver for row 0 (the group nearest the bottom of the board) I populated one component at a time, soldering each in place with a fine-tipped iron. The driver for row 1 I tried dabbing solder paste on all the pads for that driver, placing all those components, then soldering them with the iron. These took lots of time, and I had trouble keeping the components properly aligned.</p><p>The driver for row 2 I applied paste to all the pads, placed all the components, then gingerly reflowed the whole group with hot air. This worked pretty well and was much faster than the previous two. I did the same for the driver for row 3.</p><p>To try speeding things up, I did the drivers for rows 4 and 5 at the same time. This also worked well, so I did the same with rows 6 and 7. Then I populated the three small VDD bypass capacitors between the row drivers and the row select logic. With all this complete, I soldered on the two connectors.</p><p>All this mess added two hours to my estimates. For the remaining boards I think I'm going to populate entire boards at once rather than trying to partition up the work to avoid this sort of thing.</p><p> Next on the agenda is to update the debug board and tweak the Verilog for the FPGA. I may also write some 4004 assembly code to give the scratchpad registers a thorough workout.<br /></p><hr width="75%" /><p>I'm also considering investing in a proper reflow oven. Inspection showed several spots where I hadn't reflowed the solder, and these were most common where the pads were connected to the ground plane. I'd tried preheating the two inner planes (VDD and GND) from the bottom using a general-purpose heat gun, but it appears I didn't get them quite as hot as I thought I had, or they cooled before I got to the problem areas with my hot air wand. I have at least another three or four boards to make, and some of them may be six-layer boards rather than four like this one.<br /></p>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-369948448353532720.post-84219528942379468232023-09-21T21:10:00.001-04:002023-09-21T21:10:17.296-04:00Poor Prior Planning Problems<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhq8Zfq4m3eDsxgXI0LuglBM0LNCih3RZ24TvEdR9_LJiyEyJXrYhbdvelVUSYkXgFCU7NATvs9zuzwV9eoehiLn58Ou79OVqJPgfuUBrqf8nIwARhImbi1bEQsEA3n2H3CRpYl3d5PCdm9ilgqIs096H4XE191UFa4rWQxASJufDhHTbw6xqRQ90Qr5yZk/s640/MFG_TS391AX50.jpg" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="640" data-original-width="640" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhq8Zfq4m3eDsxgXI0LuglBM0LNCih3RZ24TvEdR9_LJiyEyJXrYhbdvelVUSYkXgFCU7NATvs9zuzwV9eoehiLn58Ou79OVqJPgfuUBrqf8nIwARhImbi1bEQsEA3n2H3CRpYl3d5PCdm9ilgqIs096H4XE191UFa4rWQxASJufDhHTbw6xqRQ90Qr5yZk/w200-h200/MFG_TS391AX50.jpg" width="200" /></a></div>Having received my new Scratch Pad Register boards from JLCPCB, I collected the parts I needed to populate the board. Everything was going well until I opened the container of solder paste: it was completely hard and dried out. I really should have anticipated this, since the last time I used it was three years ago. <i>*sigh*</i><br /><p></p><p><span></span></p><a name='more'></a>A new container of solder paste is only $14, and this should enough for me to finish the remaining four boards in this project. However, because of its weight, the shipping costs another $7. Rather rush to place an order and pay 50% in shipping, I spent a day looking at all the projects I'm working on and made a list of things I needed for them. I placed a combined order with DigiKey early Monday morning, for no increase in shipping cost. It arrived this afternoon.<p></p><p>Rather than try to populate and reflow the entire board in one evening — over 500 surface-mount components — I decided to do only the right 1/3rd of the board. This includes the control decode logic and refresh counters, but excludes DRAM array and its drivers. This took about 2.5 hours. Curiously, I found the slowest component to place to be the resistors, as they have to be flipped over so the marking is on top, and then rotated because I'm obsessive enough to want them all to read from the same angle. The 4-lead BSS83Ns were the next slowest, because it took extra effort to confirm their orientation. The 3-lead FDV301s were the fastest to place — about 10 seconds each — as their orientation is obvious.<br /></p><p>All this his suggests the rest of the board will take another 5 hours to assemble. Then I need to wire the additional six circuits this board requires through level shifters on my debug board so the FPGA can drive them. After that, I'll switch gears and generate a Verilog top module that uses of the Scratch Pad Register board instead of the Verilog module it currently uses.</p><p>Initially, I think I'm going to test this board alone, rather than with the Instruction Pointer board. Once that seems to work reliably I'll plug both boards into the debug board, rework the Verilog test module yet again, and test the two board together.<br /></p><p>Because of how many signals pass between the Instruction Decode and Arithmetic Logic Unit boards, they'll need to be tested as a pair. I simply don't have enough I/Os from the FPGA board to test either of these separately. That means finishing the layout of both boards and sending both out to be fabricated. I probably won't get that done for another couple of months. Hand-assembling them will take several days, as there are almost 800 components between the two. <br /></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-369948448353532720.post-27966638568004061102023-09-12T17:36:00.003-04:002023-09-12T17:37:07.968-04:00Scratchpad Register board delivered<p>This afternoon a DHL courier dropped a package at my doorstep. JLCPCB shipped it with a signature release required, but I waived the signature in advance.</p><p>I'm old enough to remember when placing a domestic mail order came with an "Allow 6 to 8 weeks for processing and shipping" disclaimer. Yet I sent this order to China electronically only 10 days ago. A week ago this physical package was in China, and now I'm holding printed circuit boards.</p><p><span></span></p><a name='more'></a>After removing the DHL shipping envelope, here's the box I received:<p></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1m8g39qkQBmQCaIlHFDvz8xXuly5xiuzxcKdfjzmKmjgGETc0Ls3CKQmACYk6r7o8UHe85T-NVoqgigIOpYiiryAgxIxMRveZHmluhYtpdFetqsCiABFn_VX0v56hkZ4Mv2sI_NgzqXYW89Xc0UwRaAoX9gfN-RB5a9SEm-2UXSvIQl3RSiYgO97Ndxu3/s2563/PXL_20230912_195601962~2.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1966" data-original-width="2563" height="245" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1m8g39qkQBmQCaIlHFDvz8xXuly5xiuzxcKdfjzmKmjgGETc0Ls3CKQmACYk6r7o8UHe85T-NVoqgigIOpYiiryAgxIxMRveZHmluhYtpdFetqsCiABFn_VX0v56hkZ4Mv2sI_NgzqXYW89Xc0UwRaAoX9gfN-RB5a9SEm-2UXSvIQl3RSiYgO97Ndxu3/s320/PXL_20230912_195601962~2.jpg" width="320" /></a> <br /></div><p>The boards come in this heavy plastic packaging. There isn't anything separating the boards from each other (there are five in this package), but the vacuum-sealed packaging keeps the boards from sliding against each other and potentially damaging the surfaces.</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhp3xGLg2DgLqAKysyKl2UnaDcsf88hsDVMtqRFhHz4_az0UF9ahdqJXKZJYkcP29ulQTmEUi6yfVsZPfMvW-STVW9RYvhvda0pes2ly2RcZlAp9INGQ63YmOV-VIcPXFlmW19R2BRlU_lFVD-wM3owNoqsv89uOmSZ5ldVHbcZ5DuuNKUnEAZbd5ptD43m/s3713/PXL_20230912_195655052~2.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="2408" data-original-width="3713" height="208" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhp3xGLg2DgLqAKysyKl2UnaDcsf88hsDVMtqRFhHz4_az0UF9ahdqJXKZJYkcP29ulQTmEUi6yfVsZPfMvW-STVW9RYvhvda0pes2ly2RcZlAp9INGQ63YmOV-VIcPXFlmW19R2BRlU_lFVD-wM3owNoqsv89uOmSZ5ldVHbcZ5DuuNKUnEAZbd5ptD43m/s320/PXL_20230912_195655052~2.jpg" width="320" /></a></div><p></p><p></p><p>The empty space in the box was filled with bubble-wrap, so nothing was sliding around during shipping. So no real worries about damage in shipping, unless someone drops something heavy and pointed on it.<br /></p><p>I also ordered a solder stencil. Some people may feel comfortable placing little blobs of solder on a board by hand, but I've tried that and it doesn't go well. The cost of the stencil ($7 plus some shipping) is well worth it to me. <br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifaVz-873R88Cwz0KRZLuDZgF2LlkMv7ErlwFi2dgcSgnxQXLrZcULc0DzqsFzda_5JtuoDlb4QathqNeRt6kUni_VGWko8pDo8dyDIpO1UriFaOpxt-kgMQmi3ZCiJPVQmMzQkZ2P-IaJCFmbAODoETE9w_TgCzsO-BZP09QEdCoB1stJPpmeuDsYvcif/s3168/PXL_20230912_195704897~2.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="2015" data-original-width="3168" height="204" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifaVz-873R88Cwz0KRZLuDZgF2LlkMv7ErlwFi2dgcSgnxQXLrZcULc0DzqsFzda_5JtuoDlb4QathqNeRt6kUni_VGWko8pDo8dyDIpO1UriFaOpxt-kgMQmi3ZCiJPVQmMzQkZ2P-IaJCFmbAODoETE9w_TgCzsO-BZP09QEdCoB1stJPpmeuDsYvcif/s320/PXL_20230912_195704897~2.jpg" width="320" /></a></div><p></p><p></p><p>The stencil came in this heavy zip-lock plastic bag to protect it from scratches. One of the tricks I've learned is to have the solder stencil cut down to
roughly the size of the board so everything fits snugly in the box.
That way you're not paying shipping for a box much larger than it needs
to be.</p><p>And finally, here's one of the boards:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiH0sNd1aAkNjk5DXiuz_RAElAqC8iixSI9DFzCpXrzDnFv2dgi17JbC7GEnRVZwEc8_WKs21nx8z8sreyFDNevrXb_nG_bGh3rTTugfSr_sKT-Ayrn1v8U323PflIXkp66pHx9F8LMAklE1ZiLNATrn_0JQYcjhALAaPgfL1TsnIeFvjjoDwlpR70ymVIk/s3168/PXL_20230912_201711252~2.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="2025" data-original-width="3168" height="205" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiH0sNd1aAkNjk5DXiuz_RAElAqC8iixSI9DFzCpXrzDnFv2dgi17JbC7GEnRVZwEc8_WKs21nx8z8sreyFDNevrXb_nG_bGh3rTTugfSr_sKT-Ayrn1v8U323PflIXkp66pHx9F8LMAklE1ZiLNATrn_0JQYcjhALAaPgfL1TsnIeFvjjoDwlpR70ymVIk/s320/PXL_20230912_201711252~2.jpg" width="320" /></a></div><p></p><p>The one issue I have every time I order boards is realizing just how small the components that go onto it are. This board is 6.6" by 4.25", but looks a lot larger when I'm viewing the layout on a 30" monitor. When I'm holding the actual board I remember what fun it will be to place the 500-some components that will go onto it.<br /></p><p><br /></p>Unknownnoreply@blogger.com4tag:blogger.com,1999:blog-369948448353532720.post-29654440753686217302023-09-02T19:37:00.005-04:002023-09-02T21:43:55.161-04:00Scratchpad Register board ordered<p>After starting the layout of the Scratchpad Register board in August 2012 — yes, 11 years ago — it has finally been sent out for fabrication by JLCPCB in China. Here's what they say it will look like:</p><p></p><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQTFMoLtz3XzZqubera1vKsDSATWpT-3stBPm8oi7HXFvRVLJ29AfWr6ySRQXBMyoKkWEQuxx2B10gVmk8ADj9UcqHY694kTZTo9Qs4wdcoMeRLHKtTxCmrgmu2-A_ygTCmbKZAqh2R8yxmiLFfrMpivqbwMzZ4_pLP3ZTxxPx1tOtKCHwV4xuynk13vTJ/s800/downImg.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="516" data-original-width="800" height="206" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQTFMoLtz3XzZqubera1vKsDSATWpT-3stBPm8oi7HXFvRVLJ29AfWr6ySRQXBMyoKkWEQuxx2B10gVmk8ADj9UcqHY694kTZTo9Qs4wdcoMeRLHKtTxCmrgmu2-A_ygTCmbKZAqh2R8yxmiLFfrMpivqbwMzZ4_pLP3ZTxxPx1tOtKCHwV4xuynk13vTJ/s320/downImg.png" width="320" /></a></div></div> <p></p><p>If they keep to schedule, production should start Monday (China time) and take 3-4 days. This would have the boards and stencil ship Friday-ish. I opted for the default DHL Express (2-4 day) shipping so they should arrive sometime the following week.<br /></p><a name='more'></a><p>The biggest change in the last two days is the addition of four 33µF tantalum capacitors on the corners, and eleven 100nF ceramic capacitors along the top and bottom edges and down the middle. These capacitors are connected between the VDD and GND planes, and serve to dampen any transients caused by state changes.</p><p></p><p>Most other changes are cosmetic. I outlined each of the subcircuits in the silkscreening, and annotated each with the function the subcircuit performs. I did this on the Instruction Pointer board, and found this makes it easier to probe the circuits with an oscilloscope. It also helps explain how the board functions to those who foolishly show interest in my insanity.</p><p>One place this annotation is especially helpful is identifying which DRAM cell represents which bit in which register. </p><p>First, here's the structure of the array according to Table III of the 1973 MCS-4 User's Manual:<br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWxLHgq78uZavK8s9A9cu3UBEigDAYBgnGhvR5FMaEfDvxucCLPwqXfQrA9Z0FRZUsGtg4JNg4Sb97qL1FdflF7UniAtr0tL-PBctpbU_xI1r410QSGl0Jqum6rxXl-sqZfltuglLtGVofRm5aK6s4QUm7s3A_Yn15frs0VhC9QBXiHMzbErGlWdj3g_b9/s868/i4004_scratchpad_registers.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="362" data-original-width="868" height="133" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWxLHgq78uZavK8s9A9cu3UBEigDAYBgnGhvR5FMaEfDvxucCLPwqXfQrA9Z0FRZUsGtg4JNg4Sb97qL1FdflF7UniAtr0tL-PBctpbU_xI1r410QSGl0Jqum6rxXl-sqZfltuglLtGVofRm5aK6s4QUm7s3A_Yn15frs0VhC9QBXiHMzbErGlWdj3g_b9/s320/i4004_scratchpad_registers.png" width="320" /></a></div><p>Looking at the board's DRAM array layout, which follows the layout in the actual chip, it appears to follow the same structure: an 8 x 8 array of DRAM cells, each row representing the eight bits of a pair of four-bit registers. However, while each row does represent a register pair, the layout of the bits is not as shown in the table. Instead, the left-most two columns represent Bit 0 of both registers in a pair, the next two columns represent Bit 1 in a pair, and so on. I'm sure this is for routing simplicity, as it places the multiplexer for each bit below the two bits it muxes. </p><p>What's odd, though, is that the order of the two bits reverses for each pair of columns. For Bit 0, the odd register bit is the column on the left and the even register bit is the column on the right. For Bit 1 these reverse; the even register bit is the left column and the odd register bit is the right column. Bit 2 has the same arrangement as Bit 0, while Bit 3 matches Bit 1. Having this sort of oddity identified on the silkscreen will avoid me
having to remember such trivia should I need to hunt down a problem.</p><p>I'm assuming this had something to do with routing of signals in the chip, but that's only a guess at this point. It might be interesting to look at the metal layers in the chip to see if the reason is clearer.<br /></p><p></p>Unknownnoreply@blogger.com5tag:blogger.com,1999:blog-369948448353532720.post-67450555363441456282023-08-31T12:45:00.002-04:002023-09-02T19:38:07.963-04:00Scratchpad board layout progress<p>I've just about completed the layout of the Scratchpad board for my Intel 4004 CPU recreation. The only big changes in the layout since <a href="http://insanity4004.blogspot.com/2016/03/preliminary-scratchpad-placement.html">2016</a>, other than the signal routing, has been to reorient some of the decoding sub-circuits on the right side of the board.<br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgS1K1ko9Jo4DnVH4O9mY4Zv4aXryl06X8WWiWlXaxRZIWAv8TPJd560mtLRzjq3amDuntGowEuVr0r2IflAvR2HuiMaqB1cS2Vs9IgAz_tHhyTuJB1oCbWXKDyu9_y56xNjteFdZCHxuotJ4mjEU5AJ0WbsrlNZTdQ7IaQBPdOyUc4cWN5aO8dv6db_2DA/s1455/Screenshot_20230831_104800.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="988" data-original-width="1455" height="271" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgS1K1ko9Jo4DnVH4O9mY4Zv4aXryl06X8WWiWlXaxRZIWAv8TPJd560mtLRzjq3amDuntGowEuVr0r2IflAvR2HuiMaqB1cS2Vs9IgAz_tHhyTuJB1oCbWXKDyu9_y56xNjteFdZCHxuotJ4mjEU5AJ0WbsrlNZTdQ7IaQBPdOyUc4cWN5aO8dv6db_2DA/w400-h271/Screenshot_20230831_104800.png" width="400" /></a></div><p></p><p><span></span></p><a name='more'></a>The ratsnest command now reports no remaining airwires (unrouted nets), and the DRC reports no errors. Hypothetically, I could generate Gerber files from this and have the board fabricated.<p></p><p>So what's left?</p><ul style="text-align: left;"><li>The DRC parameters I'm using are left over from using PCB-Pool. I don't have good Eagle DRC files for JLCPCB, so I need to create some. My spacing is wide enough that I don't expect to need to move anything.<br /></li><li>There is no decoupling between the VDD and GND planes yet. I added four tantalum capacitors on the corners of the Instruction Pointer board, and I'm going to add the same plus some ceramics to this one.</li><li>I'm going to add outlines and labels to the silkscreen for the remaining sub-circuits, as I did on the Instruction Pointer board. I've found these very helpful when probing the board (and they look nifty).<br /></li><li>While I'm pretty sure the clock issues I worried about are a non-issue for this application (nothing is edge-triggered here), I'm still thinking about adding footprints for a couple of resistors between the two clock lines and a pair of unused pins on J1.<br /></li></ul><p>Both <a href="https://us.beta-layout.com/pcb/configuration/" rel="nofollow" target="_blank">PCB-Pool</a> and <a href="https://jlcpcb.com/" rel="nofollow" target="_blank">JLCPCB</a> have produced excellent boards for me. My experience with PCB-Pool's customer service was stellar, with fewer language and time difference issues, but I really have no complaints with JLCPCB. The biggest difference is price: PCB-Pool would charge me $175 for one board ($248 if I want a second as a spare), while JLCPCB will charge me $39 for five boards. While shipping charges are a bit higher from China than from Europe, I'll pay a few dollars more in shipping to save hundreds in product costs.</p><p>Speaking of shipping charges, it pains me to pay $24 in shipping for $39 of product. I could save $10 by using the cheapest shipping method, but that would take 3-4 times longer and probably isn't trackable. My next order will probably include both the <a href="http://insanity4004.blogspot.com/2016/02/progress-on-id-board.html">Instruction Decoder</a> and <a href="http://insanity4004.blogspot.com/2016/02/progress-on-alu-board.html">Arithmetic Logic Unit</a> boards, as my current <a href="http://insanity4004.blogspot.com/2012/09/wiring-test-jig.html">test jig</a> doesn't have enough I/O pins available to test them separately. I'm expecting this will reduce the shipping cost per board. They're also laid out as 6-layer boards (this one is 4 layers), so the product costs are higher ($79 per design) for the same shipping cost.</p><p>I'm also considering having the solder stencils fabricated by <a href="https://www.oshstencils.com/" rel="nofollow" target="_blank">OSH Stencils</a> rather than JLCPCB. For some reason, adding a single minimally-sized stencil to the JLCPCB order adds $7 for the stencil <i>and</i> $8 to the shipping estimate, though I think that shipping estimate is higher than what I was actually charged for my last order. A <span class="ux-osh-orange-text">Polyimide Film stencil from </span>OSH Stencils would cost about $25 including shipping, which is about $10 more than a steel stencil from JLCPCB. However, it's easier to position a film stencil, as it is more-or-less transparent, and its flexibility would make it easier to populate the board in portions rather than all at once.</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-369948448353532720.post-47909936499234173412023-06-12T22:44:00.003-04:002023-06-12T22:51:48.518-04:00Congratulations to Klaus Scheffler<p>Way back in 2012 I came across the Intel 4004 35th Anniversary Project, which had unearthed the original schematic for the Intel 4004 CPU and related chips, and got the idea to implement the CPU using discrete components. This seemed like the kind of project that would teach me a lot, while not representing much of a risk. After all, the Anniversary Project had already done this once; I'd seen it running in an exhibit in the Intel Museum.</p><p>I had the "hobbyist" license for Eagle, which limited me to 100mm x 160mm boards. This was nowhere near large enough to implement the entire CPU, so I divided the CPU into several smaller modules. I decided my first board would implement the Instruction Pointer module. </p><p>After I assembled and tested the Instruction Pointer board, Tim McNerney informed me that they'd run out of time and funds to do a discrete component implementation, and the museum exhibit runs on a PC. Talk about a surprise; I didn't realize I was blazing a new trail. Still, thousands (millions?) of the original chip proves the basic design.<br /></p><p>I'd fully intended to complete my implementation of the CPU, but Real Life intervened and the project got shelved. Since then I've corresponded with several people who wanted information about my implementation, and I've always been happy to comply. The 4-terminal MOSFET I used, the NXP BSS83N, went out of production, and we discussed alternatives.</p><p>Now the renamed <a href="http://www.4004.com/index.html" rel="nofollow" target="_blank">50th Anniversary Project</a> has announced that Klaus Scheffler has succeeded in constructing a complete, working CPU from discrete components. Congratulations to him! </p><p>I was hoping to find details of their implementation, but the Anniversary Project website doesn't have much more than a photo of the board. Not having the constraints imposed by my Eagle license, he was able to put everything on a single board. To someone who has studied the schematics and original chip design, the functional blocks are readily apparent. I know this was Tim McNerney's original intent, and it would be much more useful in a museum exhibit than my stack of smaller boards.</p><p>Klaus tells me he used the SST-215 MOSFET throughout, which is quite similar to the NXP BSS83 I used in critical places. He also mentioned it's currently running at 25 KHz, but I don't know if that's its maximum speed.</p><p>I still plan to finish my CPU re-construction at some point. Being "first" was never part of my plan, as I thought Tim had already done this when I started. I have all the parts I need except the boards themselves, and it would be a shame to have come this far and not complete the project.<br /></p>Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-369948448353532720.post-31460717360116757342023-05-06T10:19:00.002-04:002023-05-06T10:22:10.274-04:00Back to the Scratchpad board<p></p><table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEju-1Reti6nJtg-CViyrNA4OSFl7RHumuftfmW9yonCYKBw2S7nKaWr-eiFAXu_jPpAD8LLhY2hmy9EytyoeYAfJUkSNHuWbn3_vzStU3XDOYLJpdbne316fFXPw9PQZzi-sGgGMyV-KN4-UtIRiokbJ4ERxDykjgjX1IrLg8oG4pkrwOwBuwbcHasPtg/s590/i4004_block_diagram.png" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" data-original-height="376" data-original-width="590" height="204" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEju-1Reti6nJtg-CViyrNA4OSFl7RHumuftfmW9yonCYKBw2S7nKaWr-eiFAXu_jPpAD8LLhY2hmy9EytyoeYAfJUkSNHuWbn3_vzStU3XDOYLJpdbne316fFXPw9PQZzi-sGgGMyV-KN4-UtIRiokbJ4ERxDykjgjX1IrLg8oG4pkrwOwBuwbcHasPtg/s320/i4004_block_diagram.png" width="320" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">i4004 CPU Block Diagram<br /></td></tr></tbody></table>As I mentioned in the previous post, I've started working on the Scratchpad board again. This is the board that implements the 16 x 4-bit array of internal registers.<br /><p></p><p>Internally, as depicted at the far right side of the i4004 CPU block diagram, this is actually an 8 x 8-bit DRAM array. It's quite similar to the 4 x 12-bit array used in the Instruction Pointer, which I successfully implemented some years ago.</p><span><a name='more'></a></span><p>I started laying out this board in <a href="http://insanity4004.blogspot.com/2012/08/scratch-pad-array-board.html">August 2012</a> and last worked on it in <a href="https://insanity4004.blogspot.com/2016/03/preliminary-scratchpad-placement.html">March 2016</a>. I'd been hoping to do this work in KiCad v7, but issues with the Eagle schematic importer in KiCad and some other transition concerns have convinced me to complete this project using my perpetually-licensed copy of Eagle v7.7.0.</p><p></p><p></p><div style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em; text-align: center;"><br /></div><p style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></p><p>One of my concerns when implementing the Instruction Pointer board in <a href="https://insanity4004.blogspot.com/2012/07/instruction-pointer-board.html">July 2012</a> was whether the gate capacitance of the FDV301N MOSFET that forms the DRAM storage element would be sufficient to avoid bit-rot between refresh cycles. In case it wasn't, I added 0604 capacitors in parallel with the FDV301N to the design.</p><p>My breadboard experiments in <a href="https://insanity4004.blogspot.com/2012/06/building-dram-cell.html">June 2012 </a>suggested
these would not be necessary, so when I assembled the IP board I did
not populate these capacitors. My tests with this board continue to
support this belief, but they've been run with the CPU running at 714
KHz, which is near the upper end of the original chip's operating range
of 500 to 741 KHz. Although I have planned to do margin testing of my IP
board with lower clock rates, I haven't gotten around to doing so.</p><p>The
DRAM cell layout I established with the IP board arranges the
components on a 0.16 x 0.16 inch grid, which allows the placement of
this capacitor in what would otherwise be a blank space. Rather than
kick myself later, I've added these capacitors to the Scratchpad board
as well.</p><p>Here we see the DRAM cell for bit 0 of register 0 (or register 15, I'm not positive which), with the added capacitor highlighted. Note that the layout of the DRAM array is essentially rotated 90° counterclockwise from the schematic:<br /></p><p></p><p></p><table><tbody><tr><td><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgylEXOjRHu5zuv6IVWh--XJGKXgDLZjJYOlY6a7fZf1bOi4dzo4KbSeDbfmPubgWPfsj4SSyCE873xGEPt1mtOVNYuHP_-Qx2_1MVzYRgddVF1UZb2Iu9nuep4cA4TOsTCEnviqktD5tgHHso4r0UZ6u7Gn10P1CQEoiaPL13KmOI6MuVUS9lAPRpAnQ/s416/Screenshot_20230506_084947.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="416" data-original-width="413" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgylEXOjRHu5zuv6IVWh--XJGKXgDLZjJYOlY6a7fZf1bOi4dzo4KbSeDbfmPubgWPfsj4SSyCE873xGEPt1mtOVNYuHP_-Qx2_1MVzYRgddVF1UZb2Iu9nuep4cA4TOsTCEnviqktD5tgHHso4r0UZ6u7Gn10P1CQEoiaPL13KmOI6MuVUS9lAPRpAnQ/w199-h200/Screenshot_20230506_084947.png" width="199" /></a></div></td><td><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyzsuS_1KOBf8x-sSCXw_HQytFYC36mtYh5ETykMeNyOyf2BWl1SwVs2z5ZqsRZU3p9rNnyeBFUiiornrxHC4LthHQNB5phzKJJlFUNXHA-ERWMSjEHk57_VHiQB1plXljy_xDARB4RjlFJrCsprz4Zrc0nXZJUd_6tcQCzDguh3g-TqivUrBi4Izhmw/s453/Screenshot_20230506_085435.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="300" data-original-width="453" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyzsuS_1KOBf8x-sSCXw_HQytFYC36mtYh5ETykMeNyOyf2BWl1SwVs2z5ZqsRZU3p9rNnyeBFUiiornrxHC4LthHQNB5phzKJJlFUNXHA-ERWMSjEHk57_VHiQB1plXljy_xDARB4RjlFJrCsprz4Zrc0nXZJUd_6tcQCzDguh3g-TqivUrBi4Izhmw/w320-h213/Screenshot_20230506_085435.png" width="320" /></a></div></td></tr><tr></tr></tbody></table><p>Most of the work I've done recently has been the tedious and repetitious routing of connections within the 8 x 8 DRAM array. As can be seen above, this cell hasn't been completely routed — it's missing ground connections to the drain of T1443 (lower right) and the substrate of T0474 (lower left).</p><p>I'm going to be quite busy for the next couple of weeks with other activities, so I'm thinking it may take until the end of the month to finish routing this board. I'll take a look at the Instruction Decoder and Arithmetic Logic Unit boards, then I'll send this one off to JLCPCB for fabrication. Maybe I'll have it assembled and in the test jig in early July.<br /></p>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-369948448353532720.post-13923823835452593712023-04-28T08:35:00.001-04:002023-05-29T11:35:26.163-04:00Problems importing Eagle projects into KiCad<p>This time last year ago I tried importing my Eagle project for the i4004 Scratchpad board into KiCad. My reasoning was that I'm now much more familiar with KiCad's user interface than Eagle's, and the KiCad PCB router has features not available in Eagle v7. (Later versions of Eagle have improved the router, but I'm not paying Autodesk $70/month to rent it.)</p><p>It took a few experiments to get KiCad's importer to produce results I liked, but eventually I checked the results into my version control system (I use Git). Then I began fixing the few visual problems I noted (some of these have been fixed in KiCad v7). Then I got busy with other things again and, well, you know how these things go.<br /></p><p>A few weeks ago someone posted to the KiCad forum that he was having problems importing an Eagle project. I did some more experiments importing some other Eagle projects and was able to help him through many of his issues, most of which were misunderstandings of the difference between KiCad and Eagle. However, one serious problem remained. KiCad has a tool that lets you cross-probe between symbols and nets in the schematic and footprints and tracks on the board. This is a critical feature, but it only worked with a small number of nets and tracks in an imported Eagle project. Further experiments exposed a serious flaw in the Eagle schematic importer.</p><p>Eagle supports schematics with multiple sheets. This is convenient when a schematic is too large to fit comfortably on one sheet. However, Eagle doesn't support hierarchical schematics. All Eagle nets are global to all sheets. This is very different than KiCad, where nets are local to a sheet unless explicitly made global by applying a global label to the net.</p><p>When KiCad imports an Eagle schematic, it only creates global labels for the nets that connect on multiple sheets; all other net names are dropped. However, the imported board retains all the net names assigned by Eagle. Since the cross-probing tool depends on matching net names, the result is that only inter-sheet connections and certain supply nets can be cross-probed.</p><p>If you're starting with an Eagle schematic and create the board in KiCad this is may not be a problem. However, if you've already created the board in Eagle, or explicitly named nets in your Eagle schematic, this may be a huge issue for you. Because I wanted to maintain the same net names used in the i4004 simulator, <i>all</i> of my nets have explicit net names. Losing these net names is a non-starter for me.</p><p>I reported this bug to the KiCad development team (<a href="https://gitlab.com/kicad/code/kicad/-/issues/14620" target="_blank">Issue #14620</a>) and proposed several possible solutions. However, I don't expect to see a fix for this any time soon.<br /></p><p>Thus I've reluctantly abandoned my plan to use KiCad for further development of the i4004 CPU recreation. Instead, I've started working on the Scratchpad board using Eagle v7 again.<br /></p>Unknownnoreply@blogger.com0