I couldn't sleep so I was reading Green Arrays documentation... again. I
have found that if I read and reread the Green Arrays documents along
with the web pages of Chuck Moore I find a lot of little tidbits that I
glossed over in the past.
A while back I was reading some of the EtherForth web pages and found a
little piece about subtracting the second on stack from the top... as
opposed to subtracting the top from the second as is more common in
Forth, but then the GA144 doesn't really run Forth, does it? Seems this
is a great way to compensate for the lack of a SWAP instruction, but in
addition it saves the bother of generating a literal 1! Just like the
DeMogan equivalent for logic, if you invert all the inputs and output of
an addition it is still a valid addition, but now the sense of the carry
input is inverted giving a subtraction the 1 it needs to make it a two's
complement operation. (- . + -) compared to (some code to rearrange the
operands, then - . + 1 . +) a big savings of both speed and space!
Some of the instruction timing is very complicated and the explanation
in the manual is not really very clear. But if you read it enough
especially between the lines, some of the subtleties come out. There is
a prefetch on the instructions. If any of the opcodes access memory this
requires the prefetch to start over. So depending on the highest slot
with a memory access the instruction fetch time ranges from 1.2 ns to
4.3 ns (typ). I think this is even true for IO operations. I suppose
there is only one shared address bus. I still don't get why the
execution time for an "empty" next instruction is different from a
One thing that makes the timing explanations hard to figure out is that
they use source code notation and not machine instructions, so you have
to figure out how some of the slots are filled in. Here is an example...
mul nn-n a! 17 dup dup / or for / +* unext drop / a ;
Mul is the routine name and n n - n is the stack notation. (17 DUP DUP
or) leaves 17 and zero on the stack which I believe is wrong for this
code. I expect the 'for' will be translated into a PUSH followed by two
NOPs to fill out the instruction word so the unext loop can start on an
instruction boundary. That means the loop count is 0 which will loop
just one time! It took me a while to figure this out and somewhere in
there I realized that a literal does not prevent the rest of the
instruction slots from being used. Here is code from Chuck's page, he
puts the zero on the stack first.
* a! 0 17 for +* unext a ;
But by far, the hardest part of understanding how to use the GA144 is
learning how the IO works. Admittedly I am pushing very hard on
optimization to get as much speed as I can, particularly in the ADC/DAC
and memory interface. It was only when I read Chuck's pages on the
"Blue Screen of Death" that I realized the processor pending on the bit
17 input can be done as part of the IO write to the UP register... I
think. His code is for the DAC, so he isn't reading the UP register.
I'm still not clear on the details such as does the read of UP also pend
on the input bit? I'm thinking it does, but is that edge sensitive or
level sensitive? I'm thinking it is level sensitive so it shouldn't
cause a problem with waiting for a second edge before reading the ADC
What made me write this message is when I was comparing the wall charts
for the GA32 and GA144 and realized that the otherwise undocumented SR,
DB and WD symbols are explained here! They are nowhere mentioned in the
GA144 or F18 data books!!! Looking at this chart just now I realized
that they do a poor job with the "phantom" wake up signals on bits 7 and
9, just labeling them "pin". This should be PH or similar and explained
in the chart. But squeezing one more line onto this chart may be harder
than using the GA144!
Some of the IO stuff is very complex and really doesn't seem to work
well. It is clear that the memory interface was just an idea and has
not been fleshed out in any detail. There is no way to ever make it run
at real memory speeds that I can see. I'm hoping I can get it to run
SDRAM at 50 MHz, but I won't know for sure until I get a lot of
questions answered. BTW, random writes at 50 MHz are 80 ns, a big
improvement over 250 ns SRAM cycles! Burst operations should run with
Some of the things I find in these late night sessions are disappointing
because they make it hard to use this chip and waste performance and
memory speed. But other things seem to shine with the brilliance of a
clever mind. Mostly I am frustrated by the lack of proper
documentation and app notes.
I may have a real application for this part, but the GA144 may be too
expensive, especially when multiple support chips need to be added. A
standard MCU/DSP (like the Motorola Cortex M4) may turn out to be a
better choice. If there was a $5 GAxx part available it would fill a
lot more sockets than the $15 GA144 will.
Re: GA144 Documents
Let me add that ultimate speed is the tail of the market. I have some very interesting ideas that could get by with a 10K or 100K clock. But I need minimal outside world interfaces - in one case 1.8 to 3.6 V (it varies over time). And in another 5V I2C stuff. If I get the volumes up I might ask Chuck to design me a chip. But start out with a GA144 or a GA32? Not a chance.
Re: GA144 Documents
rickman <email@example.com> writes:
> What made me write this message is when I was comparing the wall
> charts for the GA32 and GA144 and realized that the otherwise
> undocumented SR, DB and WD symbols are explained here! They are
> nowhere mentioned in the GA144 or F18 data books!!!
Have you looked at the Seaforth chip docs? They are more thorough than
the GA stuff, and the chips are pretty similar.