TTL Counter with tri-state - Page 1
Forum section: electronics / projects

author: obiwanjacobi
author_rank: Super Contributor
timestamp: February 12, 2020, 06:25:41 pm
content: Looking for a cheap option to count 18 bits but with output enable (tri-state).Have looked at the 74x590 (more than 10,= euro a pop @ Farnell) 74x593 not available.At Ali and ebay this kind of chip is either not available or pricey as well.Context:I am trying to make an address counter for a TTL VGA project and need to be able to access the video memory this counter addresses from the CPU bus. I figured if I could get a counter that I could tri-state I would not need any muxes (or addition dirvers with OE) and would save a couple of precious nanoseconds. I run the pixel clock at 25.175 Mhz and have little less than 40ns to get a pixel out, 15ns are taken by the SRAM I plan to use.I have the usual counters in stock (74x161 and 74x393) as well as a butt load of 245's...One option I have considered is using two GAL 22V10's to build the counter. That would actually be a pretty nice fit (also have them in stock - and already use them in the design).

author: rstofer
author_rank: Super Contributor
timestamp: February 12, 2020, 10:10:38 pm
content: You seem to have some expensive solutions to a $5 problem. 5 chips, $1/each => $5 if I read it right. Maybe a little more for qty 1 but you gave the qty 10 price.Here's my approach: My time is billed at $100/hour, even for hobby work. A proper $5/solution can be substituted with any other as long as the parts cost + the labor cost is cheaper. So, even if I had alternate, but useless, chips on hand and they were totally free, I couldn't spend more than 3 minutes thinking about it before I just ordered the proper parts.Using this labor rate is why I don't do plumbing under my sink while standing on my head. I hire somebody for that kind of thing. Same with the landscape service. And other stuff... Unless I can do it cheaper at my internal billing rate, I won't do it at all. Sometimes I don't even care what the outside cost is, I don't climb ladders at my age.Time has a price, pick a number.

author: oPossum
author_rank: Super Contributor
timestamp: February 13, 2020, 04:35:09 am
content: Quote from: obiwanjacobi on February 12, 2020, 06:25:41 pm74HC590 is ~$0.50. Making it work with TTL/NMOS is usually just a matter of some pull-up resistors.

author: obiwanjacobi
author_rank: Super Contributor
timestamp: February 13, 2020, 06:08:16 am
content: Did not think to search for HC parts...Thanks @oPossum. The 590 has registers to store the count bits - which complicates things a bit.Can I tie the register- and counter-clocks together to sort of bypass the registers...? Or will the (considerable) delay times make that unstable?Or does anybody know any other counters without registers but with tri-state outputs?{I've always wondered how other people do their parts selection in the design stage...? And how do you know where to choose from?}Quote from: rstofer on February 12, 2020, 10:10:38 pmI can give you a screen shot of the Farnell page but you probably bill me for looking at it

author: cj
author_rank: Contributor
timestamp: February 13, 2020, 10:18:01 am
content: The 74F579 is synchronous 8bit up/down counter with bi-directional 8bit interface so it has tri-state output.I haven't seen these in other technologies though so it might be hard to find.CJ

author: obiwanjacobi
author_rank: Super Contributor
timestamp: February 13, 2020, 10:30:42 am
content: Not on Farnell and 6,= on ebay... ouch!

author: JagV12
author_rank: Contributor
timestamp: February 13, 2020, 10:38:22 am
content: Quote from: obiwanjacobi on February 13, 2020, 06:08:16 amYou can at least delay the counting clock (or use inverted /clock if available). Counter output will be one count behind but timing will be accurate. Just make sure the Reset pin is triggered accordingly.

author: obiwanjacobi
author_rank: Super Contributor
timestamp: February 13, 2020, 10:48:37 am
content: This counter counts the video memory address.If I invert the (pixel!) clock and trigger on the neg-edge, I fear I will not have enough time to get the pixel data. Less than 40ns are available per pixel and my memory needs at least 15ns...

author: JagV12
author_rank: Contributor
timestamp: February 13, 2020, 11:10:55 am
content: Quote from: obiwanjacobi on February 13, 2020, 10:48:37 amThat's why I suggest you delay the Counting clock and not the Register clock. The count is one step behind but you keep all of the 40ns

author: obiwanjacobi
author_rank: Super Contributor
timestamp: February 13, 2020, 12:02:46 pm
content: But the address counter needs to keep pace with the Horizontal counter too. Both run of the pixel clock:Pixel Clock => Horizontal Counter => Decoder => HSync, NewLine, EnableAddress (etc)Pixel Clock & EnableAddress => Address Counter => Video RAMIf I delay the address counter the pixels come in late relative to where the horizontal counter is at that time...I have separated these because I have shrunken the pixel display window with borders.I use 640x480 VGA mode but have only 512x384 pixels. I use EnableAddress to signal my visible window is active.Should I design this differently?

author: SiliconWizard
author_rank: Super Contributor
timestamp: February 13, 2020, 02:37:08 pm
content: Quote from: obiwanjacobi on February 12, 2020, 06:25:41 pmLooks like you are often putting off using programmable logic for your projects, but I think you should definitely take the plunge (unless your projects are 100% "vintage" designs and you don't want any modern chip in them.)GALs these days are pretty limited compared to current CPLDs/small FPGAs. Considering them would make your life greatly easier IMO.Maybe one of your constraints is that your designs are usually on 5V, and that you'd need to use a lot of level shifters? Is this constraint completely necessary? If you're accepting to use more modern parts, I think most of what you'd need (even for discrete logic) would be available in 3.3V (except maybe the very specific logic ICs that are "obsolete") But I don't know exactly what your goal is, so maybe you don't really have a choice.

author: obiwanjacobi
author_rank: Super Contributor
timestamp: February 13, 2020, 03:07:42 pm
content: The idea was to build it using discrete logic components in order to fully understand the intricacies of building a VGA adapter. Reading others talk about is different from getting your hands dirty. Also this knowledge could come in handy when I do finally take the plunge and go full FPGA.I now take a hybrid approach in using TTL logic as well as a couple of GALs - for instance for the decoding logic to save a lot of gates. Not having to deal with level shifting is a bonus. So you could say its a goal to do it in TTL as a deliberate learning curve - that is my choice. No other requirements or constraints exist - except interfacing with a Z80 (5V) eventually...

author: SiliconWizard
author_rank: Super Contributor
timestamp: February 13, 2020, 03:49:51 pm
content: Quote from: obiwanjacobi on February 13, 2020, 03:07:42 pmUnderstand.Quote from: obiwanjacobi on February 13, 2020, 03:07:42 pmAs I said, a lot of discrete logic ICs are available in 3.3V these days, so going "TTL" is not really necessary IMO, you could get the same result at 3.3V (and have more choice in ICs except maybe for the odd vintage specialized TTL ICs with specific functions....)Now if you're going to interface with a Z80, that's another story - of course there are Z80's that can run @3.3V (CMOS series), so that wouldn't be a show-stopper either unless you absolutely need to interface with an old and existing Z80 system.In this case, using external level shifters is still an option - you can design your whole additional circuitry for 3.3V, and just use a few level shifters. As mentioned in another thread, there are level shifters at 1 bit to 16 bits, so that would be just a few additional ICs and would still give you the opportunity to use otherwise much more recent ICs.

author: TomS_
author_rank: Frequent Contributor
timestamp: February 13, 2020, 06:08:24 pm
content: Quote from: SiliconWizard on February 13, 2020, 03:49:51 pmAre you sure about that? I've looked into this in the past, and the inputs very definitely wanted much more than 3.3V for a guaranteed logic high.Also the power supply requirements were above something like 4.5V.Edit: apologies, inputs only need 2.2V+ (I guess for TTL backward compatibility), but the power supply must be 4.5V+ for CMOS.Unless there's a variant that I am not aware of... But that is for the Z84C00xx which are the only CMOS parts I know of.

author: SiliconWizard
author_rank: Super Contributor
timestamp: February 13, 2020, 06:49:06 pm
content: Quote from: TomS_ on February 13, 2020, 06:08:24 pmTechnically, the Z84C00 series was not spec'ed at 3.3V, but I've heard of a few people successfully making them run @3.3V @4MHz or so. Probably a bit on the edge here.To avoid running things out of spec though, your best bet would be to use the Z180 series. Still easily available. Significantly lower power. Many additional goodies inside, but still 100% compatible. Can run at 3.3V up to 20MHz (eg.: Z8L18020) Kind of the Z80 many people wish they had back in the day.

author: rstofer
author_rank: Super Contributor
timestamp: February 13, 2020, 09:13:21 pm
content: Quote from: obiwanjacobi on February 13, 2020, 12:02:46 pmIf you use a modern FPGA, you will have BlockRAM which can be configured as dual port. The CPU reads/writes into one side of the RAM and the VGA gadget reads from the other side - often using a completely separate clock.I saw the term Z80 above and, based on just that, I'm going to recommend you look at the T80 core over at OpenCores.org and perhaps whatever is left of PacMan at fpgaarcade.com. This is a perfect example of recreating a vintage arcade game with a single chip. Unfortunately, the site has gone commercial and you need to look at the 'wayback' version of the site:http://web.archive.org/web/20130702025031/http://www.fpgaarcade.com/pac_main.htmI have that game running on a Digilent Nexys 2 board (long obsolete).Chips become obsolete when nobody uses them and discrete TTL is certainly on the not-often-used list. It's just too much easier to use an FPGA.Designing with chips is interesting but truly obsolete. Just the pin count gets out of hand. Most pins require 1 or 2 wires and for a design with 50 chips of 16 pins eachm we're talking at least 1600 wire-wrap connections. Doing the artwork for a PCB is even more insane. Draw the block diagram, figure out the gating logic and use these as reference when coding an FPGA.I mentioned earlier my philosophy of an internal billing rate. True, nobody on the planet would pay me that kind of money, but the idea is to prevent me from going down an unproductive rabbit hole.I can create a 32 bit register with a single line of code or 8 each 4-bit D-flops plus sockets and wiring. No way is discrete hardware competitive with typing at 100 WPM.

author: obiwanjacobi
author_rank: Super Contributor
timestamp: February 14, 2020, 06:01:38 am
content: I did not start a computer build by first building the VGA adapter.So the Z80 is a 5V version - that part is already built.I explained why I want to do TTL, so no FPGA (for now).Last evening I've tried to code a counter in CUPL. Tried and failed.Some CUPL examples used a syntax that WinCUPL did not like -even though they said it would be compatible-.Seems like the version I've got has an issue with nested $Repeat loops (like thishttps://stackoverflow.com/questions/28385578/how-to-create-a-n-bit-counter-using-gal-programming-in-wincupl)Also examples from the WinCUPL reference/manual itself did not work!?I run my WinCUPL on a WinXP (SP3) machine because it crashed on Win10...?I am trying to figure out how the logic works for each bit of the counter.So what is the principle behind this code? -is it even correct?(Append => OR, Qn.D is setting a D-FF input)Code:Append Q0.D = !Q0;Append Q1.D = !Q1 & Q0;Append Q1.D = Q0 & !Q1;$Repeat P = [2..7]$Repeat R = [{P - 1}..0]Append Q{P}.D = Q{P} & !Q{R};$RepEndAppend Q{P}.D = !Q{P} & !([Q{P-1}..0]:#);$RepEndQ0 I get: just flip the bit on each clock and you have bit 0 of the counter.Q1 has two of the same equations - the operands are just swapped around.If I roll out the macro for Q2 it would be something like:Code:Append Q2.D = Q2 & !Q1;Append Q2.D = Q2 & !Q0;Append Q2.D = !Q2 & !([Q1..0]:#);I was unfamiliar with that last syntax and I cannot find it in the CUPL reference but I think it expands to something like:Code:Append Q2.D = Q2 & !Q1;Append Q2.D = Q2 & !Q0;Append Q2.D = !Q2 & !(Q1 # Q0);This is where I get lost ...I cannot see the technique used here to count...

author: oPossum
author_rank: Super Contributor
timestamp: February 14, 2020, 07:42:18 am
content: Learn a little VHDL and let the computer figure it out.Code:if rising_edge(clk) thenn <= n + 1end if;

author: obiwanjacobi
author_rank: Super Contributor
timestamp: February 14, 2020, 08:41:58 am
content: Quote from: oPossum on February 14, 2020, 07:42:18 amThat teaches me nothing...

author: oPossum
author_rank: Super Contributor
timestamp: February 14, 2020, 10:58:20 am
content: Equations from that VHDL...Code:count_0_.D = ( !count_0_.Q );count_0_.C = (clk);count_1_.D = ( !count_0_.Q & count_1_.Q# count_0_.Q & !count_1_.Q );count_1_.C = (clk);count_2_.D = ( !count_0_.Q & count_2_.Q# !count_1_.Q & count_2_.Q# count_0_.Q & count_1_.Q & !count_2_.Q );count_2_.C = (clk);count_3_.D = ( !count_0_.Q & count_3_.Q# !count_1_.Q & count_3_.Q# !count_2_.Q & count_3_.Q# count_0_.Q & count_1_.Q & count_2_.Q & !count_3_.Q );count_3_.C = (clk);count_4_.D = ( !count_0_.Q & count_4_.Q# !count_1_.Q & count_4_.Q# !count_2_.Q & count_4_.Q# !count_3_.Q & count_4_.Q# count_0_.Q & count_1_.Q & count_2_.Q & count_3_.Q & !count_4_.Q );count_4_.C = (clk);count_5_.D = ( !count_0_.Q & count_5_.Q# !count_1_.Q & count_5_.Q# !count_2_.Q & count_5_.Q# !count_3_.Q & count_5_.Q# !count_4_.Q & count_5_.Q# count_0_.Q & count_1_.Q & count_2_.Q & count_3_.Q & count_4_.Q & !count_5_.Q );count_5_.C = (clk);count_6_.D = ( !count_0_.Q & count_6_.Q# !count_1_.Q & count_6_.Q# !count_2_.Q & count_6_.Q# !count_3_.Q & count_6_.Q# !count_4_.Q & count_6_.Q# !count_5_.Q & count_6_.Q# count_0_.Q & count_1_.Q & count_2_.Q & count_3_.Q & count_4_.Q & count_5_.Q & !count_6_.Q );count_6_.C = (clk);count_7_.D = ( !count_0_.Q & count_7_.Q# !count_1_.Q & count_7_.Q# !count_2_.Q & count_7_.Q# !count_3_.Q & count_7_.Q# !count_4_.Q & count_7_.Q# !count_5_.Q & count_7_.Q# !count_6_.Q & count_7_.Q# count_0_.Q & count_1_.Q & count_2_.Q & count_3_.Q & count_4_.Q & count_5_.Q & count_6_.Q & !count_7_.Q );count_7_.C = (clk);

author: obiwanjacobi
author_rank: Super Contributor
timestamp: February 14, 2020, 11:17:55 am
content: Thanks!I can see the pattern and the logic now. Seems to me that the example on stackoverflow was wrong.It uses OR (#) instead of AND (&) for the last case where the bit is check for 'all lower bits set and own bit clear'...Basically each bit output has conditions that will set the bit when true just before the next clock pulse. So you're testing the 'previous' condition, just before that bit is to become (or stay!) active.Learned something new!

author: obiwanjacobi
author_rank: Super Contributor
timestamp: February 14, 2020, 01:12:02 pm
content: Quote from: obiwanjacobi on February 14, 2020, 11:17:55 amIt is not wrong - it's just inverted.