fastspin has x := if condition then eval_if_true else eval_if_false. This means adding one keyword, "then", but I think it's easier to read than C's version.
I think I like the C syntax better although maybe that's just because I'm used to it. Your syntax has too many identifiers in a row without any delimiters other than spaces to separate them. Although maybe that's because you've given a general case. This doesn't look quite so confusing:
This seems like a nice idea, although I'd probably swap the order of the count and array (that way there's no ambiguity about whether count is a user parameter or not -- anything after an array parameter is something inserted by the compiler.
I guess that depends upon which order the params end up on the stack. You want the count on top, I think, so you know how far down the param[] array extends.
Also, I like x := if a > 2 then a - 1 else a in lieu of a > 2 ? a - 1 : a.
It seems like there is a lot of discussion on the new Spin syntax, operator names and other things that have no impact on the silicon. I thought the sudden urgency of getting Spin working on the P2 was to uncover potential issues with the hardware design before it goes out to synthesis. Changing Spin syntax and operator names doesn't do a thing toward that goal, and in fact only delays the silicon even more. I was hoping for a merry Chipmas this year, but it seems more and more doubtful when I see all the random tweaks that are suggested for New Spin.
I tend to agree, but hopefully Chip is not taking too much notice of the higher level syntactic sugar diversions, and instead focuses on getting r16 images, and then byte-code engine tested on as many vehicles as possible - including XIP flows.
Tachyon is an obvious one.
I've been really looking forward to a ternary operator in Spin2. It makes code very compact in Verilog, especially when you have several of them.
Ideally, such a structure can also push all the way to code generation, and for smallest IF-ELSE choices, use a skip-style code generate. ie not jumps, but condition-code fall-thru.
Small skips will work much better with XIP code fetch, which has a relatively high cost attached to a jump, but less cost attached to skips, or serial code.
Interesting, Phil. That never occurred to me before.
I've been fighting Delphi most of the day. Turns out it blows up with 4k screen resolution. Had to back things down a bit.
The -A9 and -A7 compiles are all done now. It's strange that in the Cyclone V architecture, if utilization gets over ~93%, the compiler drags on for several hours and if it ever even finishes, the resulting Fmax is really poor.
Currently, I'm waiting for the DE2-115 compile to finish.
Interesting, Phil. That never occurred to me before.
I've been fighting Delphi most of the day. Turns out it blows up with 4k screen resolution. Had to back things down a bit.
The -A9 and -A7 compiles are all done now. It's strange that in the Cyclone V architecture, if utilization gets over ~93%, the compiler drags on for several hours and if it ever even finishes, the resulting Fmax is really poor.
Currently, I'm waiting for the DE2-115 compile to finish.
Fabulous!
Waiting for Quartus can be painful, especially when the final synth goes all weird.
Has there been any discussion of what to do with the ALTx and AUGx instructions? Will they appear on their own in source code or is the assembler expected to generate them automatically for new addressing modes? Has anyone come up with the syntax for those extended instructions? It seems like ALTx and AUGx?
Has there been any discussion of what to do with the ALTx and AUGx instructions? Will they appear on their own in source code or is the assembler expected to generate them automatically for new addressing modes? Has anyone come up with the syntax for those extended instructions?
Certainly where possible, the assembler should be able to generate them automatically, in which case they would appear in the LISTING file as 2 lines of ASM. ie managed in code flow, rather like any MACRO is.
Has there been any discussion of what to do with the ALTx and AUGx instructions? Will they appear on their own in source code or is the assembler expected to generate them automatically for new addressing modes? Has anyone come up with the syntax for those extended instructions? It seems like ALTx and AUGx?
ALTx is a prefix instruction and will always appear in source code.
AUGx is generated by Pnut when using immediate values with the ## option.
Only thing I see is that SETSE1/2/3/4 could move into one of the spare slots above which could allow the POLLINT..NIXINT3 to use SSSSSSSSS=000100000 which then affects the xxx/SETINT1/2/3and drops another line of spares at SSSSSSSSS=0001001ff.
Are all of the jump and branch instructions relative now? There are no absolute ones?
from the file "instructions_v15.txt"
For immediate-branch and LOC address operands, "#" is used before the
address. In cases where there is an option between absolute and relative
addressing, the assembler will choose absolute addressing when the branch
crosses between cog and hub domains, or relative addressing when the
branch stays in the same domain. Absolute addressing can be forced by
following "#" with "\".
Are all of the jump and branch instructions relative now? There are no absolute ones?
from the file "instructions_v15.txt"
For immediate-branch and LOC address operands, "#" is used before the
address. In cases where there is an option between absolute and relative
addressing, the assembler will choose absolute addressing when the branch
crosses between cog and hub domains, or relative addressing when the
branch stays in the same domain. Absolute addressing can be forced by
following "#" with "\".
Okay, I see. The absolute ones are in a different place in the instruction spreadsheet that I missed on my first glance. Sorry for the dumb question.
Why oh why do we need the horrible confusion of ternary expressions?
In fastspin's case I needed a ternary operator internally to implement some ranged bit expressions (things like outa[x..y] := z needed different handling depending on whether x < y). Since I had to implement it anyway it was trivial to expose it to the user. It's actually pretty common -- I think even Algol had it didn't it? (I'm sure Algol68 did, at least.)
Only thing I see is that SETSE1/2/3/4 could move into one of the spare slots above which could allow the POLLINT..NIXINT3 to use SSSSSSSSS=000100000 which then affects the xxx/SETINT1/2/3and drops another line of spares at SSSSSSSSS=0001001ff.
Probably not worth changing ???
The spare slots within CLKSET..QEXP are not worth using because that whole range is decoded as %00000xxxx, so that the 4 LSB's form hub commands. The other slot values get filled in with COGINIT..QVECTOR codes.
It would be neat to not use the D field for POLLINT..NIXINT3 and just use the S field, since there's plenty of space available. Wish I had done that. Would have kept things simpler and cleaner.
Only thing I see is that SETSE1/2/3/4 could move into one of the spare slots above which could allow the POLLINT..NIXINT3 to use SSSSSSSSS=000100000 which then affects the xxx/SETINT1/2/3and drops another line of spares at SSSSSSSSS=0001001ff.
Probably not worth changing ???
The spare slots within CLKSET..QEXP are not worth using because that whole range is decoded as %00000xxxx, so that the 4 LSB's form hub commands. The other slot values get filled in with COGINIT..QVECTOR codes.
That makes sense
It would be neat to not use the D field for POLLINT..NIXINT3 and just use the S field, since there's plenty of space available. Wish I had done that. Would have kept things simpler and cleaner.
Yes. Using S certainly contributed a lot of instruction expansion space when S wasn't required.
The instruction space is nice and tidy now. Did you see my latest post above where it breaks out the instruction space? eg see ROLBYTE
Did AUGS & AUGD need to be 2 clocks or was it just easier to keep it standard?
Why oh why do we need the horrible confusion of ternary expressions?
In fastspin's case I needed a ternary operator internally to implement some ranged bit expressions (things like outa[x..y] := z needed different handling depending on whether x < y). Since I had to implement it anyway it was trivial to expose it to the user. It's actually pretty common -- I think even Algol had it didn't it? (I'm sure Algol68 did, at least.)
I'm not opposed to ternary operators but can't help wondering how many ways we need to do the same thing, and how terse do we want to make them.
Why oh why do we need the horrible confusion of ternary expressions?
In fastspin's case I needed a ternary operator internally to implement some ranged bit expressions (things like outa[x..y] := z needed different handling depending on whether x < y). Since I had to implement it anyway it was trivial to expose it to the user. It's actually pretty common -- I think even Algol had it didn't it? (I'm sure Algol68 did, at least.)
I'm not opposed to ternary operators but can't help wondering how many ways we need to do the same thing, and how terse do we want to make them.
The advantage is that the ternary operator can be used in an expression. A regular if statement can't.
Comments
I think I like the C syntax better although maybe that's just because I'm used to it. Your syntax has too many identifiers in a row without any delimiters other than spaces to separate them. Although maybe that's because you've given a general case. This doesn't look quite so confusing:
Also, I like x := if a > 2 then a - 1 else a in lieu of a > 2 ? a - 1 : a.
-Phil
I've been really looking forward to a ternary operator in Spin2. It makes code very compact in Verilog, especially when you have several of them.
I tend to agree, but hopefully Chip is not taking too much notice of the higher level syntactic sugar diversions, and instead focuses on getting r16 images, and then byte-code engine tested on as many vehicles as possible - including XIP flows.
Tachyon is an obvious one.
Ideally, such a structure can also push all the way to code generation, and for smallest IF-ELSE choices, use a skip-style code generate. ie not jumps, but condition-code fall-thru.
Small skips will work much better with XIP code fetch, which has a relatively high cost attached to a jump, but less cost attached to skips, or serial code.
a := 50 if a < 5 else a * 10
a := 5 if a < 5
This puts the condition in the middle of the ternary operator and eliminates the then keyword.
-Phil
I've been fighting Delphi most of the day. Turns out it blows up with 4k screen resolution. Had to back things down a bit.
The -A9 and -A7 compiles are all done now. It's strange that in the Cyclone V architecture, if utilization gets over ~93%, the compiler drags on for several hours and if it ever even finishes, the resulting Fmax is really poor.
Currently, I'm waiting for the DE2-115 compile to finish.
Waiting for Quartus can be painful, especially when the final synth goes all weird.
AUGx is generated by Pnut when using immediate values with the ## option.
The instruction set decodes nice and clean.
Only thing I see is that SETSE1/2/3/4 could move into one of the spare slots above which could allow the POLLINT..NIXINT3 to use SSSSSSSSS=000100000 which then affects the xxx/SETINT1/2/3and drops another line of spares at SSSSSSSSS=0001001ff.
Probably not worth changing ???
I am not sure either if we really need them. It is just that they are pretty common lately.
But they just make sense in the common used form
exp ? true-part : false part.
if not in that common form its just another quirk with spin.
and stuff like
a := 50 if a < 5 else a * 10
a := 5 if a < 5
is not much shorter then
if a < 5 a := 50 else a *= 10
if a < 5 a := 5
just ugly
Mike
I think a single line if-else is worthwhile, but I'm less convinced a special new syntax is needed.
the alternative example above of
if a < 5 a := 50 else a *= 10
looks just fine to me. The then is implied, so no new keyword is required.
In fastspin's case I needed a ternary operator internally to implement some ranged bit expressions (things like outa[x..y] := z needed different handling depending on whether x < y). Since I had to implement it anyway it was trivial to expose it to the user. It's actually pretty common -- I think even Algol had it didn't it? (I'm sure Algol68 did, at least.)
The spare slots within CLKSET..QEXP are not worth using because that whole range is decoded as %00000xxxx, so that the 4 LSB's form hub commands. The other slot values get filled in with COGINIT..QVECTOR codes.
It would be neat to not use the D field for POLLINT..NIXINT3 and just use the S field, since there's plenty of space available. Wish I had done that. Would have kept things simpler and cleaner.
The instruction space is nice and tidy now. Did you see my latest post above where it breaks out the instruction space? eg see ROLBYTE
Did AUGS & AUGD need to be 2 clocks or was it just easier to keep it standard?
Is RDLUT 3 clocks for both cog-exec and lut-exec?
Is WRLUT 2 clocks for both cog-exec and lut-exec?
I'm not opposed to ternary operators but can't help wondering how many ways we need to do the same thing, and how terse do we want to make them.
Why can't we convert the current SPIN1and just use the existing bytecodes?
The inline assembly can be added next.
Then we can consider what needs changing/fixing/extending.
We don't want to really break the existing P1 spin code do we???
c := (a < 5 ? 5 : a) * 10
That's its primary utility, not just as a single-line if/else.
-Phil
Spin1 byte codes are limited to a 64k memory map.
That's right. It's awfully handy.