Electronics > Projects, Designs, and Technical Stuff
TTL Counter with tri-state
rstofer:
--- Quote from: obiwanjacobi on February 13, 2020, 12:02:46 pm ---Should I design this differently? :-//
--- End quote ---
If 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.htm
I 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.
obiwanjacobi:
I did not start a computer build by first building the VGA adapter. :o
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 this https://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!? :wtf:
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};
$RepEnd
Append Q{P}.D = !Q{P} & !([Q{P-1}..0]:#);
$RepEnd
--- End code ---
Q0 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]:#);
--- End code ---
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);
--- End code ---
This is where I get lost ...
I cannot see the technique used here to count...
oPossum:
Learn a little VHDL and let the computer figure it out.
--- Code: ---if rising_edge(clk) then
n <= n + 1
end if;
--- End code ---
obiwanjacobi:
--- Quote from: oPossum on February 14, 2020, 07:42:18 am ---Learn a little VHDL and let the computer figure it out.
--- Code: ---if rising_edge(clk) then
n <= n + 1
end if;
--- End code ---
--- End quote ---
That teaches me nothing... :-//
oPossum:
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);
--- End code ---
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version