Prop2 FPGA files!!! - Updated 19 November 2017 - Version 27a

134689103

Comments

  • I guess I don't understand debugging/interrupts...
    What happens if I fail to set the interrupt vectors?
    Prop Info and Apps: http://www.rayslogic.com/
  • The all cogs blink example has really changed a lot!

    Am I see this:
    ROM bootloader loads cog0 with HUB RAM from $000 to $3FF and then executes from cog address 0?

    Somehow coginit is reading hub longs at $400 to set debug info?
    Prop Info and Apps: http://www.rayslogic.com/
  • Rayman wrote: »
    I guess I don't understand debugging/interrupts...
    What happens if I fail to set the interrupt vectors?

    When a cog starts executing user code, a debug interrupt immediately occurs and the cog jumps to where its INA's shadow register points. The tiny cog-startup ROM in the cog sets that pointer to $400+cogid*4. There needs to be some instruction there to receive the branch. If you want to debug, make it a JMP to somewhere. If you want it to immediately release and not come back, make it an RETI0.
  • Chip,
    Can this behavior be turned on by a bit in COGINIT like the start in hubexec bit?
  • Rayman wrote: »
    The all cogs blink example has really changed a lot!

    Am I see this:
    ROM bootloader loads cog0 with HUB RAM from $000 to $3FF and then executes from cog address 0?

    Somehow coginit is reading hub longs at $400 to set debug info?

    If a COGINIT has D[5] clear, $1F8 longs are loaded from hub @PTRB into cog registers $1F0..$1F8 and a JMP to $000 executes.

    If a COGINIT has D[5] set, a JMP to PTRB executes.
  • Ok, I think I see it now... I think I'm with Roy though, wishing there was a spare bit to turn off the initial interrupt...
    Prop Info and Apps: http://www.rayslogic.com/
  • Roy Eltham wrote: »
    Chip,
    Can this behavior be turned on by a bit in COGINIT like the start in hubexec bit?

    It could be, but that would mean interfering with the code base, somewhat. The way it is now, you could practically debug an entire application without getting into the target code.
  • We could change it, of course.

    We need to figure out where to inject this functionality, if not at the outermost level.
  • RaymanRayman Posts: 8,327
    edited October 2015 Vote Up0Vote Down
    Maybe the HUB interrupt vectors now at $400 can instead be HUB registers that are initialized by ROM to RETIO?

    I hate to sound negative, btw, grateful for the updated files :)

    BTW: I think I like the addition of interrupts and debugging. But, I'd rather that it didn't interfere in any way with usage without those things...
    Prop Info and Apps: http://www.rayslogic.com/
  • ozpropdevozpropdev Posts: 1,956
    edited October 2015 Vote Up0Vote Down
    Chip
    I have the following hub code which produces this error
    		orgh	$2000
    
    go		mov	p2pa_mode,#0
    		jmp	@go2      '<-- Error  '"Relative addresses cannot cross between cog and hub domains."
    
    go1		mov	p2pa_mode,#1
    
    go2		mov	reg0,adra		'save adra
    
    What am I missing here?

    Edit: I replaced all my relative jmp/call references in my hub code for absolute and all working now.
    It seems Pnut doesn't like relative addresses in Hub code?
    Melbourne, Australia
  • ozpropdev wrote: »
    Chip
    I have the following hub code which produces this error
    		orgh	$2000
    
    go		mov	p2pa_mode,#0
    		jmp	@go2      '<-- Error  '"Relative addresses cannot cross between cog and hub domains."
    
    go1		mov	p2pa_mode,#1
    
    go2		mov	reg0,adra		'save adra
    
    What am I missing here?

    Edit: I replaced all my relative jmp/call references in my hub code for absolute and all working now.
    It seems Pnut doesn't like relative addresses in Hub code?

    My error. I had put that check into the assembler, but forgot to limit it to the second pass. I'm posting a "B" version now at the top of this thread. Thanks for pointing this out.
  • SeairthSeairth Posts: 2,244
    edited October 2015 Vote Up0Vote Down
    Chip,

    Along the idea of adding a bit for the debug ability, couldn't that just prevent/mask the debug interrupt? I'm thinking something like:

    D/# : %x_xdhN_nnnn

    xx : not used (yet ;) )
    d : 0 = normal operation, 1 = debug interrupt (working as you describe above)
    h : 0 = load cog from PTRB and start at $0, 1 = JMP to PTRB
    N : 0 = init cog nnnn, 1 = init next available cog (nnnn ignored)
    nnnn: cog number to use when N=0

    (note: I'm guessing that S/# is stored in PTRB on coginit?)
  • cgraceycgracey Posts: 8,306
    edited October 2015 Vote Up0Vote Down
    These 16 debug interrupt instructions at $400 allow for NSA-style complete interdiction of all cog execution. It's scary! It has a price, though: Your freedom to do whatever you want with hub memory. This is the debug solution for our brave new world. We could make it work on a per-cog basis, but why bother? That'd be like getting warrants, or something. What do you guys want? Are you willing to give up a little freedom here? Are you wondering if you even have a choice?
  • cgracey wrote: »
    These 16 debug interrupt instructions at $400 allow for NSA-style complete interdiction of all cog execution. It's scary! It has a price, though: Your freedom to do whatever you want with hub memory. This is the debug solution for our brave new world. We could make it work on a per-cog basis, but why bother? That'd be like getting warrants, or something. What do you guys want? Are willing to give up a little freedom here? Are you wondering if you even have a choice?

    Well, here's the thing. If I wanted to debug code loaded in the cog, couldn't I get the same effect by defining a debug_start routine in hub memory that would:

    1. Copy $1F8 longs to cog memory
    2. Set the debug address (in INA shadow register)
    3. set the debug breakpoint to the start address
    4. JMP to start address

    Then, whenever I want to debug a cog, I coginit cog_num, @debug_start. Wouldn't this give me the same result as what you have? Similarly, if I want to debug hub code, wouldn't the process be the same as above, except step 1?

    (note: yes, I would somehow need to pass the start address, but I could use the same registers you are using in your scheme. only, in my case, I can organize those wherever I want. Or use a stack. Or whatever.)
  • Seairth wrote: »
    cgracey wrote: »
    These 16 debug interrupt instructions at $400 allow for NSA-style complete interdiction of all cog execution. It's scary! It has a price, though: Your freedom to do whatever you want with hub memory. This is the debug solution for our brave new world. We could make it work on a per-cog basis, but why bother? That'd be like getting warrants, or something. What do you guys want? Are willing to give up a little freedom here? Are you wondering if you even have a choice?

    Well, here's the thing. If I wanted to debug code loaded in the cog, couldn't I get the same effect by defining a debug_start routine in hub memory that would:

    1. Copy $1F8 longs to cog memory
    2. Set the debug address (in INA shadow register)
    3. set the debug breakpoint to the start address
    4. JMP to start address

    Then, whenever I want to debug a cog, I coginit cog_num, @debug_start. Wouldn't this give me the same result as what you have? Similarly, if I want to debug hub code, wouldn't the process be the same as above, except step 1?

    (note: yes, I would somehow need to pass the start address, but I could use the same registers you are using in your scheme. only, in my case, I can organize those wherever I want. Or use a stack. Or whatever.)

    That would work, of course. It would necessitate changing the code, though.

    The way it is now with these vectors, you could debug whatever cog you wanted, without needing to get deep into what might be some indirect COGINIT setup. All you'd need to know is the cog number, and you could do it. It might be an interesting way to trap all kinds of profiling data with no cog being the wiser. It's really like the NSA now.
  • Chip
    I'm still getting the same error as above with the "B" version of Pnut.
    Melbourne, Australia
  • Lol, careful what you ask for.
    Do not taunt Happy Fun Ball! @opengeekorg ---> Be Excellent To One Another SKYPE = acuity_doug
    Parallax colors simplified: http://forums.parallax.com/showthread.php?123709-Commented-Graphics_Demo.spin<br>
  • ozpropdev wrote: »
    Chip
    I'm still getting the same error as above with the "B" version of Pnut.

    I just downloaded from the new link and it is the new version. I verified I can do @ branches in hub space.

    Are you sure you didn't mix up the old and new files, somehow?
  • ElectrodudeElectrodude Posts: 1,111
    edited October 2015 Vote Up0Vote Down
    What if you make the debug interrupt global to all cogs? Then there would be only one long lost of hubram, and maybe it could be moved out of hubram into some global hub register. If you want debug only some cogs, then your debug handler could just immediately RETI0 when it gets run on cogs you don't want to debug.

    Another big advantage of this is that you won't have to tell coginit which cog to use if you want to use debugging - you can let it start whichever cog it likes via D[4], and then have the debug interrupt handler look at ptrb and see whether or not the code should be debugged or if it should just immediately RETI0.
  • What if you make the debug interrupt global to all cogs?

    Err, would that not mean, you cannot debug more than 1 cog ?

  • jmg wrote: »
    What if you make the debug interrupt global to all cogs?

    Err, would that not mean, you cannot debug more than 1 cog ?

    It would mean that the debug ISR would have to determine which cog he is and branch, again, to the appropriate handler.

    I've just been playing around with this tonight and it is very powerful. It really is like the NSA. You can trap every cog starting up, and maintain a little database of what cog was started when, at what address, and then poll them to find out what they are doing, later. Imagine being able to just get a snapshot of any cog, at any time, with no setup, aside from the code monkeying with the vectors and some debug workspace. It's pretty wild! No need to plant hooks in your code, either. It just works.
  • cgracey wrote: »
    jmg wrote: »
    What if you make the debug interrupt global to all cogs?

    Err, would that not mean, you cannot debug more than 1 cog ?

    It would mean that the debug ISR would have to determine which cog he is and branch, again, to the appropriate handler.

    I've just been playing around with this tonight and it is very powerful. It really is like the NSA. You can trap every cog starting up, and maintain a little database of what cog was started when, at what address, and then poll them to find out what they are doing, later. Imagine being able to just get a snapshot of any cog, at any time, with no setup, aside from the code monkeying with the vectors and some debug workspace. It's pretty wild! No need to plant hooks in your code, either. It just works.

    You sound pretty excited about this Chip so I am certainly intrigued enough to start playing with it as soon as I'm done with getting my software back to the point it was with the previous FPGA. Once I have an interactive environment running I will start to have some fun with this "debug" method.

    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    Tachyon Forth News Blog
    TACHYON DEMONSTRATOR
    Brisbane, Australia
  • cgracey wrote: »
    ozpropdev wrote: »
    Chip
    I'm still getting the same error as above with the "B" version of Pnut.

    I just downloaded from the new link and it is the new version. I verified I can do @ branches in hub space.

    Are you sure you didn't mix up the old and new files, somehow?

    Chip
    I thought I made the mistake of running the old version but I am running the correct version.
    I think Pnut is Ok now.
    I am getting the same error but this time they are "real" and I am changing some of my relative jumps to absolute.
    My code doesn't work anymore so it needs some tweaks to fit the new changes.

    On the subject of Pnut version and FPGA image version, is it possible for the info dialog in pnut to reflect its real version and the required matching FPGA image version. The info dialog is the same as it was in all the P2-Hot pnut versions.



    Melbourne, Australia
  • As this code is... cogs 2 and 3 blink at one hz and cog0 lights up but doesn't blink, but if I uncomment the ' djnz cognum,@:loop, it blinks at the same rate as cogs 2 and 3. So, if the djnz is in there, the cog0 falls through, but if there is no djnz, it doesn't?
    con
    myval = 25_000_000
    dat
    		orgh	0
    '
    'launch cogs #2,#3
    'look at effect of djnz
    		org
    :loop
    	'	djnz	cognum,@:loop
                    coginit	#2,#@blink
                    coginit #3,#@blink
    cognum		long	1
    '
    ' blink
    		org
    
    blink		cogid	x		'which cog am I?
    		setb	dirb,x		'make that pin an output
    		notb	outb,x		'flip its output state
    		waitx	##myval		'wait that many clocks
    		jmp	@blink		'do it again
    
    x		res	1		'variable at cog register 8
    
    ' Cog 0..15 initial debug interrupt vectors
    '
    		orgh	$400
    
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    
  • Looks like you posted the wrong code as there isn't anything in :loop. However you need djns so that when there is a coginit in the loop it also executes for cog 0 which is also the one running the loop so that finally it never exits the djns loop since it has been coginit'd. Otherwise your code is falling through to the cognum as if it were an instruction. I think that's correct.
    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    Tachyon Forth News Blog
    TACHYON DEMONSTRATOR
    Brisbane, Australia
  • cgraceycgracey Posts: 8,306
    edited October 2015 Vote Up0Vote Down
    ozpropdev wrote: »
    cgracey wrote: »
    ozpropdev wrote: »
    Chip
    I'm still getting the same error as above with the "B" version of Pnut.

    I just downloaded from the new link and it is the new version. I verified I can do @ branches in hub space.

    Are you sure you didn't mix up the old and new files, somehow?

    Chip
    I thought I made the mistake of running the old version but I am running the correct version.
    I think Pnut is Ok now.
    I am getting the same error but this time they are "real" and I am changing some of my relative jumps to absolute.
    My code doesn't work anymore so it needs some tweaks to fit the new changes.

    On the subject of Pnut version and FPGA image version, is it possible for the info dialog in pnut to reflect its real version and the required matching FPGA image version. The info dialog is the same as it was in all the P2-Hot pnut versions.



    Could you post a snippet of code that is failing?

    Good idea about starting to use version numbers. I'll do that.

    P.S. I understand now that PNut is okay, after all. I just didn't read carefully enough the first time.
  • I am trying to get Tachyon to compile and work properly but so far no joy. The compiler is touchy about the position of the intvecs, as it often says "Hub origin already exceeds target" or I get an error on coginit source of "constant must be from 0 to 511". I guess I am not quite fully understanding all the orgs and orghs and how they affect the compiler itself. I chopped out most of the code but unless I have a small program I get an error.

    Here's a test version that worked fine on the last version of the FPGA and PNut.
    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    Tachyon Forth News Blog
    TACHYON DEMONSTRATOR
    Brisbane, Australia
  • Chip
    There seems to be an issue with the ORG directive
    If I try to place my register at any nominated cog address the program fails.
    dat		orgh	0
    
    		org
    
    		setb	outb,#8
    		setb	dirb,#8
    
    		getcnt	temp
    		addcnt	temp,delay
    		waitcnt
    
    		setb	dirb,#0
    		setb	outb,#0
    
    :loop		getcnt	adra
    		testb	adra,#22 wz
    		setbnz	outb,#8
    		jmp	#:loop
    
    		'org	$100   'code fails with line included
    
    temp		long	0
    delay		long	50_000_000 * 2
    
    '
    ' Cog 0..15 initial debug interrupt vectors
    '
    		orgh	$400
    
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    
    Can you confirm that the special registers are back at the top of cog ram.

    Melbourne, Australia
  • ozpropdev wrote: »
    I am getting the same error but this time they are "real" and I am changing some of my relative jumps to absolute.

    I thought RJMPs could go from anywhere, to anywhere ?
    (just like AJMPs)

  • cgraceycgracey Posts: 8,306
    edited October 2015 Vote Up0Vote Down
    ozpropdev wrote: »
    Chip
    There seems to be an issue with the ORG directive
    If I try to place my register at any nominated cog address the program fails.
    dat		orgh	0
    
    		org
    
    		setb	outb,#8
    		setb	dirb,#8
    
    		getcnt	temp
    		addcnt	temp,delay
    		waitcnt
    
    		setb	dirb,#0
    		setb	outb,#0
    
    :loop		getcnt	adra
    		testb	adra,#22 wz
    		setbnz	outb,#8
    		jmp	#:loop
    
    		'org	$100   'code fails with line included
    
    temp		long	0
    delay		long	50_000_000 * 2
    
    '
    ' Cog 0..15 initial debug interrupt vectors
    '
    		orgh	$400
    
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    		reti0
    
    Can you confirm that the special registers are back at the top of cog ram.

    The reason that 2nd ORG wasn't working was because it was only setting the cog origin, and not advancing within the hub image. use ORGF $100 to fill to cog $100, so that things are properly positioned.

    There is another problem that I totally didn't anticipate. When you get to $100 in your cog image, beginning from hub $00000, you are already at $400! We need to change some things around.

    Either...

    hub $00000..$007FF = cog image
    hub $00800..$0083F = debug vectors

    ...or...

    hub $00400..$0043F = debug vectors (lowest possible hub-exec addresses)
    hub $00800..$00FFF = cog image

    Neither seems that great, do they? What to do here?

    Having these debug hooks SOMEWHERE provides a lot of surprising capabilities. It almost seems like cog exec and lut exec space should move to the END of hub RAM, as that will be where data wants to live, normally, trailing all executable code. Nobody will be inclined to put code there, I think, so it's useful for cog/lut exec space.

    What if...


    hub $00000..$0003F = cog r/w event 16 longs (already the case, but currently covered by initial cog image)
    hub $00040..$0007F = initial debug interrupt instructions (16 RETI0s/JMPs)
    hub $00080+ = initial cog image

    hub $00000..$FFBFF = hub exec range
    hub $FFC00..$FFDFF = lut exec range (notice that lut-to-cog exec potential)
    hub $FFE00..$FFFFF = cog exec range

    I don't how to make this look pretty, but there may be a simple way. Actually ORG would take care of this.

    Importantly, this makes all lower memory just RAM, with the first 32 longs serving some fixed purposes. This moves cog/lut exec addresses to the hinterlands, where nobody probably cares about placing code, as it is the domain of large data buffers. This makes a lot of sense, I think.
Sign In or Register to comment.