7
\$\begingroup\$

I APOLOGIZE THAT THIS IS GETTING LONG-ish. There are many updates at the end, and I begin editing the original to bring some finding and WARNINGs into it.

BACKGROUND

I am building myself a Z80 breadboard computer from scratch. It has 64 kB RAM and an 8 kB EEPROM (28C64). I have the EEPROM mapped in a mode where writes go to RAM and reads from ROM when address lines A13, A14, and A15 are low, /MREQ is low, and /WR is high. I can do that all with just one stage of a 74LS04 hex inverter and a 74HC32 quad 2 input OR gate. All well and good. Except I have this crazy desire to allow the system to re-program its own EEPROM for "firmware upgrades". Today I almost broke off a pin taking the EEPROM out one time to often, so I really want to get this programming mode done. I had it almost working. But it's unreliable.

The issue is the EEPROM /WE line doesn't behave like an SRAM /WE line. It's not a level latch, it requires a low-pulse of 100 ns to 1 μs. Here is the timing specification from the AT28C64 data sheet:

enter image description here

Someone said that setup time might be an issue, but on a Z80 it is definitely not an issue, because the address lines and /MREQ appear way before /WE, separated by an entire clock cycle, with an optional ability to make the CPU /WAIT for several more cycles.

enter image description here

FIRST IDEAS

Here is what I came up with, and it's sometimes working and sometimes it isn't working. So it's unreliable. (BTW, I cannot find the schematics editor any more?!)

enter image description here

The 3-position switch SW1 here sets the ROM addressing mode. In the middle it's the normal mode, read from ROM, write to RAM. On the high side it's ROM off, read and write from RAM. On the low side it's ROM on even for write, that, together with the /WE pulse should allow firmware upgrade.

C1 may even have been 10 nF and it also worked, or worked better even. The first time I put this together I even had R1 being 1 kΩ. No idea how this worked, but it did. Sometimes.

To make sure I didn't mess anything else up, I can run my computer in super slow mode and manually push a button of the kind that Ben Eater did his first manual EEPROM programmer.

enter image description here

He used R1 = 680 Ω. I have 330 Ω, the pulse needs to be short. So with this and if I push the button exactly when the /MREQ and /WR and /CS,ROM light come on, I could program a few bytes in. So I know my general set-up works. I just can't get the pulse right.

I figure the 74LS04 can sink 20 mA in output low state. 1 nF at 5V contains 5 nC when fully charged, and so at 20 mA (20 mC/s) it would take me 5 nC / 20 mC s, or 0.5 μs. So that should be just fine. With the R1 = 330 Ω, I would have 15 mA going through, that would still be 0.33 μs, well above the minimum of 100 ns.

Yet, it's not working. And I don't understand how it could have worked with a C1 = 10 nF and R1 = 1 kΩ. Yet, it has, once or twice in odd hours of the night.

I figured, perhaps the 74LS04 cannot sink enough current or so, or that it doesn't source enough to recharge C1 in high state. So I tried with a BJT and the R2 = 10 kΩ that Ben Eater used.

enter image description here

but to no avail.

WARNING As one respondent here said: while this does create a low-going pulse at the falling edge, it also creates a -- possibly chip-destroying!! --- high pulse at the rising edge! And this is true. Be warned, I actually just blew a chip with a mere button and a 1 nF capacitor!

As you can see here on the bench, the circuit creates a nice square wave of a few 100 ns in size on the falling edge. Don't worry about it being positive pulse instead of a negative, I just simulated this all around a single 74HC14 Schmitt-trigger inverter.

enter image description here

here is the input side, yellow trace is the falling edge of the buffer after the button. The blue trace is the capacitor acting on the falling edge, creating our pulse. This is the good side of the theory that is working as Ben Eater has taught. But warning, while yellow is scaled at 1 V/div, the blue trace is at 2.5 V/div for a reason!

enter image description here

Now look at ugly other side of the input, the rising edge.

enter image description here

it reaches levels twice the height of the normal 5 V high.

After taking several shots of this, my poor final inverter stage that had the capacitor input got shot so many times, it started failing. The chip got hot. It would still recover once. Then a zombie-like death state occurred, where it's still switching DC, somewhat, but when actually hit by changing levels, just breaks down. Chip fried, death by capacitor.

So therefore, now with the scope, I can possibly imagine that my following observation might be due to a subtle injury of the /WE input. I had observed -- without a scope -- "Last night it had worked. And today I wanted to show it off and now again I just can't get it to work any more."

Fortunately, so far, when plugging the chip into my Arduino based EEPROM programmer, it still works. So my old EEPROM chip might have barely escaped death by capacitor.

I still want something simple but reliable enough that it would work any time of day. So I will still try my transistor based approach, but modified so as to not create a recovery pulse higher than 5.5 V.

Theoretical Experiments with LTspice

Sadly, LTspice doesn't come with a library of real existing logic gates. There should be a set of 74LS and HC and HCT gates, but I don't have one. I tried to set Isink=20mA, but I don't trust that I am setting these parameters correctly.

However I have a hunch that in some situations the down spike doesn't even go all the way to ground. This is part of the issue, but anyway the approach is wrong because of the death threat to the EEPROM.

LTspice might actually under-estimate the problem with the chip-destroying capacitor pulse on the up-slope. I could see that up pulse, twice the level of Vcc, but didn't want to think it would be bad in practice. Yet it is. It's not reduced I think because the Iout is only in the μA range while Isink is 8 or 20 mA, no. Has nothing to do with current coming out of the pin, it's about what comes out of the capacitor. I assumed that Ben Eater's simple button also doesn't have this problem because the R2 = 10 kΩ, but I was wrong as my scope pictures above prove.

The next circuit I will test is what I ended up trying with LTspice. This here appears to limit the recovery over-voltage on the rising edge. But I will see this on the breadboard next. [Update to come later today, the following is still all just theoretical.]

enter image description here

So, V2 is my input square wave. Now I have 50% duty cycle because I think I'm going to go with an inverted /WE (or WE, active high). Right out of U1A.

Reason is that I realized if I drive C right out of the gate output pin, it's not going to pull low enough. And all the weird C1 = 10 nF and R1 = 1 kΩ trickery is just magic that depends on the clock speed and the time into the multiple runs and whatever magic.

Because I don't really know how to set correct parameters for the inverter gate of LTspice to match a 74LS04, HC04 or LS14 schmitt trigger, I just use two different resistors with diodes in or out of the output pin. This configuration is supposed to emulate the 74LS14 with only 8 mA sink current when low and 0.4 mA source current when high.

Then I adjusted the R1 and R2 to pull low enough. There is some tolerance here. The over-voltage at the re-charge seems perhaps below chip-killing levels now [WARNING: unconfirmed speculation!], and if I use the schmitt inverters, then I could run it through 2 more stages of it to clean that up.

Practical Test of the BJT Circuit

I now built the circuit that I have come up with and found that indeed the BJT somehow does not create the 2 x Vcc killer-pulse. There is a small hump above Vcc but it remains well inside the range (especially because my Vcc is somewhat low anyway.) I don't care about the exact values of R and C right now, just the principle. Here is the best result with the 74HC14 schmitt-trigger (yes, this is the one that got its input pin 9 fried by the killer-pulse.)

enter image description here

I was curious how the other 3 alternatives gates would perform here. And I show the results. First the 74LS04 which I like to use because it worked well for me as an oscillator for 1-4 MHz or less. But clearly for this purpose it fails.

enter image description here

The low pulse is barely there, possibly in spec for the EEPROM, but not reliable because it comes immediately up, 99% of the RC curve is irrelevant and the pulse only at the tiny tip. Not going to be reliable. Next with the 74HC04, it is slightly better:

enter image description here

and you might complain that it just should never be done without the help of Mr. Schmitt. But it is better with the HC non-schmitt than with the LS schmitt:

enter image description here

The benefit of the BJT circuit is that it doesn't do the killer pulse, and possibly pulls stronger to zero than if the previous output was directly connected to the capacitor. But the actual delay is hard to manage, and not even very good for the LS14 schmitt trigger.

Now I will proceed building all the other proposed solutions.

Best and Simplest Approach -- its practical difficulties and work-around.

I want to mention a really cool answer came in the form of a comment by the ever helpful Bruce Abbott. He said to just use a MHz clock and the problem is resolved. I did that, and it didn't work, for me, yet. Today with the scope I see that the Arduino alone doesn't provide enough power. The 74LS04 I use as an oscillator only outputs 2.7 V or so. When I connect a 3 A 5V power supply, I get a little higher. But never to 5 V. Anyway high enough to clock the Z80, so with the external power supply it probably would work.

However, now the problem is that the Arduino Nano, which I use as to serve Z80's IO requests, cannot keep up. It doesn't have enough time to throw the /WAIT line when it receives the /RE & /IORQ, interrupt doesn't trigger fast enough. So this method would work if I did not rely on the Arduino in high speed mode. I suppose I could use slow mode to copy the content into RAM first, then count down a 22 bit counter. Would take forever in 1 kHz mode, but in 4 MHz mode would take a few seconds (I measured in 4 MHz clock in HALT mode the M1 flashes at 1 MHz). Once the write is complete, CPU would go into HALT and I can see the red light come on. Then I can switch back to the 555 clock and be done with it.

The fun thing is, I can bootstrap myself to this because once I move the flash image into RAM, I can execute it from there.

\$\endgroup\$
16
  • 1
    \$\begingroup\$ Am suspecting some missing information regarding setup time. Activating the EEPROM's /CS while simultaneously pulsing its /W line with a short pulse seems dangerous. More commonly, /MREQ is more closely associated with memory /CS along with address decoding, and occurs earlier than /W. \$\endgroup\$
    – glen_geek
    Aug 20, 2022 at 18:55
  • \$\begingroup\$ "The issue is the EEPROM /WE line doesn't behave like an SRAM /WE line. It's not a level latch, it requires a low-pulse of 100 ns to 1 μs." - which EEPROM? \$\endgroup\$ Aug 20, 2022 at 20:18
  • \$\begingroup\$ @BruceAbbott sorry, I didn't say it is an AT28C64 (one of the two good used chips form the bad chips saga.) \$\endgroup\$ Aug 20, 2022 at 20:23
  • 2
    \$\begingroup\$ "What a pain without a scope." - you really need a scope. Good used analog scopes can be bought from auctions sites for not much money. 20MHz and 2 channels is plenty enough for working with the Z80. \$\endgroup\$ Aug 20, 2022 at 20:24
  • \$\begingroup\$ If you use '/WE Controlled' write timing then you shouldn't need to modify the /WR signal. \$\endgroup\$ Aug 20, 2022 at 20:28

4 Answers 4

3
\$\begingroup\$

Pulse Generator

The problems you're having could well be being caused by the relatively slowly rising output from your RC network. Digital devices don't like slowly changing analogue levels crossing their input threshold levels.

So, I have added a schmitt trigger after the RC network.

The 1k5 resistor (R1) has a value to limit the current being pulled from the output of IC1a which can only supply about 4mA whilst maintaining its output within specification.

The 1k resistor (R2) works in conjunction with IC1b's input clamping diode to limit the clamping diode's current to about 4.5mA when the output of IC1a swings negative and the right hand side of C1 drops to -5 V.

\$\endgroup\$
6
  • \$\begingroup\$ I have built yours (with slightly different values), strangely my 74HC32 and the 74HC14 didn't play well with each other. I don't know what happened. Need to get a scope to figure this out. I am still trying to go without the Schmitt trigger, even if that is heretic. Reason is that I tend to use the 74LS04 inverter as an oscillator once I want a MHz clock, and the oscillator doesn't want to work with the Schmitt trigger version. So, I swapped the HC14 back with the LS04, and the result was that I corrupted my EEPROM -- but that's a good thing! It means it finally wrote something. :) \$\endgroup\$ Aug 21, 2022 at 15:11
  • \$\begingroup\$ @GuntherSchadow The 74LS04 doesn't have enough output high drive capability to drive that 1k5 resistor in my circuit with sufficient voltage. Only 0.4mA output high current available. \$\endgroup\$
    – user173271
    Aug 21, 2022 at 21:08
  • \$\begingroup\$ I love your answer. I just built it with the HC14, HC04, LS14, and LS04. Slightly different values C1 = 1nF (smallest value I have right now) and R1, R2 = 1k. I assume this can be tweaked. But what is so nice is that it works with my preferred LS04, and I already have the /WE signal inverted, so all I need is one more inverter stage on the same chip, which I have handily available. I love your answer. Got scope pictures, but due to all this commotion I keep it to myself. \$\endgroup\$ Aug 26, 2022 at 15:19
  • \$\begingroup\$ BTW, initially I was very worried that the -Vcc negative pulse at the rising edge would again destroy an input of another one of the inverter stages. But I was glad to see that once hooked up, that negative going pulse was less than 10% of Vcc. You already took that into consideration, right? \$\endgroup\$ Aug 26, 2022 at 15:32
  • \$\begingroup\$ @GuntherSchadow Yes, that was what I was trying to describe in the last paragraph of my answer. \$\endgroup\$
    – user173271
    Aug 26, 2022 at 16:13
7
\$\begingroup\$

With your pulse forming circuit, when the active device pulls low, a short 0 volt pulse is produced and that will be OK but, when the active device goes back to producing a high level (ready to initiate the next low pulse), the action of doing so raises the WE line to nearly twice Vcc. This might prove problematic or even a chip-killer.

If this is solved (yes, there are ways) then a lower-level problem might be the way the low pulse naturally returns to a high-level i.e. it will be a sloppy-looking RC charge through R1 and C1.

I would recommend using a Schmitt trigger EXOR gate where one of the inputs is delayed by an RC network.. When "1" is applied, the EXOR output will become "1" immediately and, fall low roughly after about one RC time constant. Of course, what I have described can be inverted to suit your actual needs. But, it will produce a pulse on either input edge so, maybe this circuit might be better: -

enter image description here

Image from here and, if you want to extend the pulse you can add another series pair of inverters or, as similarly suggested earlier, add an RC low pass to the circuit after the inverter whilst using a Schmitt trigger AND gate: -

enter image description here

\$\endgroup\$
5
  • \$\begingroup\$ chip killer! ouch! right, I see, this is reminiscent to a voltage multiplier circuit. Your idea with the XOR, using an RC there, would that not also be prone to kill the XOR? (I had more XOR chips fail in my life than any other, haha). Schmitt trigger, I could use Schmitt inverters, yes, should that be necessary. \$\endgroup\$ Aug 20, 2022 at 18:41
  • 1
    \$\begingroup\$ @GuntherSchadow I've made a more sensible recommendation using an AND gate and an inverter. Explanation given. Circuit added. \$\endgroup\$
    – Andy aka
    Aug 21, 2022 at 17:31
  • \$\begingroup\$ I wish logic gates came individually in TO-92 packages or something. I am space constrained. I wanted this to be a small simple add-on :( But yes, something like this is possible, especially using a NAND .. 74LS132. \$\endgroup\$ Aug 21, 2022 at 17:42
  • \$\begingroup\$ @GuntherSchadow they are available in single packages these days but they are surface mount and not TO-92 \$\endgroup\$
    – Andy aka
    Aug 21, 2022 at 17:46
  • \$\begingroup\$ Chip killer warning is confirmed. Even if I do not choose your answer as the final one (I am going to try them all, including yours) I'd like to award you a special "notable answer" badge for this warning nobody else had caught! \$\endgroup\$ Aug 25, 2022 at 6:41
4
\$\begingroup\$

Any digital logic taking RC outputs must have Schmitt trigger inputs. You may also consider using a monostable instead of the discrete approach.

But none of that's necessary. CD4000 series will give you the pulse lengths you need when operated from 5V:

schematic

simulate this circuit – Schematic created using CircuitLab

The output switches on each input edge.

Input and output waveforms

If the initial delay is too long, then another option is to use 74HC86 + 74HC244:

schematic

simulate this circuit

Input and output waveforms

\$\endgroup\$
3
\$\begingroup\$

My go-to method for extending a pulse with RC uses a transistor to short the capacitor. That offloads the burden of capacitor discharge current onto something a lot more capable:

schematic

simulate this circuit – Schematic created using CircuitLab

enter image description here

When its base is brought high, Q1 discharges Ct very quickly, which brings the input to U2 almost instantly low. After Q1's base returns low, the capacitor recharges sedately via Rt, which delays the return to a high state of U2's input.

This thing's even resettable mid-pulse; on the graph see how a second input pulse that arrives before the output returns to zero causes the pulse to duration to be extended by the full amount.

Since these transitions are quite fast, even with the "slow" charging of Ct, probably fast enough to avoid oscillation of U2. However, I would strongly recommend that U2 be a schmitt trigger input device, to keep its output transitions nice and sharp.

I think input IN should be OK from a 74LS output (U1). I couldn't tell you how long the pulse would last if U2 is a heavy 74LS load, but if U2 is a 74HC device, the output pulse duration will be about 1RC.

I notice in your own schematics two problems:

  • You drive a 74HC input directly from a 74LS output. That's just asking for trouble, don't do it. Their switching thresholds are incompatible. When mixing LS outputs and HC inputs, use the 74HCT variants, which have inputs designed for exactly that. If you absolutely have no choice, add a 470Ω pull-up resistor from the 74LS device's output, to +5V, to give help raise the potential to what a 74HC expects.

  • You drive the base of a bipolar junction transistor, whose emitter is grounded, directly from a logic IC output. That's also asking for trouble. Even if nothing breaks, that poor transistor will take forever recovering from very deep saturation. Put a resistor between the IC output and the transistor's base. Choose a resistor that will pass enough current to fully saturate the transistor, but not so much that it can't recover quickly.

Edit: Long input pulse, short output pulse

Notes: Ignore voltage source V2 (node S) in these diagrams, it's just there to get the graphs right. When using capacitive timing elements, which are rapidly charged or discharged (with a transistor, or diode clamp, for example) you need to ensure that the power supply is sufficiently decoupled nearby. Otherwise you'll mess up the supply rail voltages shared by the entire system. I recommend a ceramic capacitor of an order of magnitude greater than the timing capacitor, directly across the supply rails nearby.

First, take a look at using an RC differentiator, whose output is diode clamped to within the supply rails:

schematic

simulate this circuit

enter image description here

Here we differentiate the input signal, producing a short negative going pulse as the input falls, and a positive going pulse when the input rises. The pulses are offset by +5V, and we suppress the positive pulse with D1.

This almost certainly will not work with IN coming from a 74LS output, because IN must be a near-full amplitude 5V to 0V transition.

If the pulse duration you require is of the order of tens of nanoseconds, then AndyAKA's answer is better, adapted here to conform to your requirement for low pulses:

schematic

simulate this circuit

enter image description here

There must be an odd number of inverters there. Each additional inverter extends the output pulse duration by its own propagation delay of about 15ns or so, depending on your particular IC.

Of course you may use any delay element that inverts, in the place of those inverters, so if you require longer output pulse durations, you can use the trusty RC delay again:

schematic

simulate this circuit

enter image description here

D1 in that last circuit is not for input protection, it's just to cause a high input to recharge the capacitor more quickly, so it's ready sooner for the next cycle. You may omit D1 if that's not important.

Finally, I'll put all these ideas into something that will work with an output from any logic device, and also use a transistor to both invert and quickly charge the timing capacitor. If anything does what you want, it's this one:

schematic

simulate this circuit

enter image description here

Edit: Another thing

I have spent a lot of time interfacing older equipment to modern digital ICs, and that has led me to accumulate a lot more 74HCT and 74ACT devices than the regular HC and AC variants, simply because of the 74LS-to74HC dilemma.

My experience with the very problems you are facing has taught me one thing: The 74HCT132 is the most important thing to have in your parts drawer. It's a quad 2-input NAND with schmitt trigger, TTL compatible inputs. Get some. Get lots. It can be connected to operate as an inverter, but is more flexible (which is why I prefer it over the 74HCT14), and is a drop-in replacement for (almost) any 74'00 you find in the wild.

\$\endgroup\$
4
  • \$\begingroup\$ Thanks for the tips regarding mixing LS and HC. About your wave forms, they look like the typical monostable use case, where a single pulse will trigger a defined square wave, including past any input bouncing. But I need the opposite: a long low should generate a low going pulse on its falling edge. \$\endgroup\$ Aug 21, 2022 at 15:06
  • \$\begingroup\$ @GuntherSchadow Not sure what you mean by that. Can you explain the input waveform and expected output to me? It's hard to extract from your question. \$\endgroup\$ Aug 21, 2022 at 15:18
  • \$\begingroup\$ @SimonFitch Input goes low, short negative going output pulse generated, input returns high some time later. \$\endgroup\$
    – user173271
    Aug 21, 2022 at 21:10
  • \$\begingroup\$ @GuntherSchadow OK, I added a few ideas for you to try. \$\endgroup\$ Aug 22, 2022 at 5:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.