strange subroutine behaviour

"Soft PrOcessor Core" - or "SPOC"

strange subroutine behaviour

Postby raalst » Sat Oct 22, 2005 12:43 pm

Hi all,
maybe someone else sees what I am doing wrong here.

I have some working code, reading a char from RX and returning the char
plus a carriage-return via TX.

as soon as I put in a subroutine, things stop working.

any feedback appreciated.

the working code is :
Code: Select all
// SPOC program for reading out a flash chip
// this works

initialize:
// set stack pointer, grows to 0x0FFF
  do #0x0C00 -> SP

Begin:

GetChar:
  do #0x3000 -> RA0
  do.bit @
  jmp.Z=0 #GetChar
// read the inchar on address 2000hex into accumulator
  do #0x2000 -> RA1
  do.byte @ -> A
//
  do #0x1000 -> WA0
  do.byte A -> @  // transmit one byte out of RS-232 TX
// check the RS-232 TX busy bit
Loop1TxD_busy:
  do #0x1000 -> RA0
  do.bit @
  jmp.Z=1 #Loop1TxD_busy

//
  do.byte #0x0D -> A // cr char
  do.word #0x1000 -> WA0
  do.byte A -> @  // transmit one byte out of RS-232 TX
// check the RS-232 TX busy bit
Loop2TxD_busy:
  do #0x1000 -> RA0
  do.bit @
  jmp.Z=1 #Loop2TxD_busy
//
//
final:
// once string completely sent, delay before sending again
Delay:
  do.dw #200000 -> A
DelayLoop:
  dec.dw A
  jmp.z=1 #DelayLoop
  jmp #Begin


// that's all folks


and the broken code is :
Code: Select all
// SPOC program for reading out a flash chip
// THIS DOES NOT WORK

initialize:
// set stack pointer, grows to 0x0FFF
  do #0x0C00 -> SP

Begin:
  jsr #GetChar // uses RA0,RA1,A.byte
//
  do #0x1000 -> WA0
  do.byte A -> @  // transmit one byte out of RS-232 TX
// check the RS-232 TX busy bit
Loop1TxD_busy:
  do #0x1000 -> RA0
  do.bit @
  jmp.Z=1 #Loop1TxD_busy
//
  do.byte #0x0D -> A // cr char
  do.word #0x1000 -> WA0
  do.byte A -> @  // transmit one byte out of RS-232 TX
// check the RS-232 TX busy bit
Loop2TxD_busy:
  do #0x1000 -> RA0
  do.bit @
  jmp.Z=1 #Loop2TxD_busy
//
//
final:
// once string completely sent, delay before sending again
Delay:
  do.dw #200000 -> A
DelayLoop:
  dec.dw A
  jmp.z=1 #DelayLoop
  jmp #Begin


//subroutine getchar
// uses RA0, RA1, output into A.byte
GetChar:
  do #0x3000 -> RA0
  do.bit @
  jmp.Z=0 #GetChar
// read the inchar on address 2000hex into accumulator
  do #0x2000 -> RA1
  do.byte @ -> A
//


// that's all folks
Regards,
Ronald van Aalst
raalst
 
Posts: 13
Joined: Tue Sep 27, 2005 7:28 pm
Location: netherlands

Postby fpga4fun » Sat Oct 22, 2005 5:15 pm

You need a RET instruction at the end of the subroutine.
fpga4fun
Site Admin
 
Posts: 837
Joined: Thu Sep 18, 2003 6:47 am

fixed but still broken

Postby raalst » Sat Oct 22, 2005 8:55 pm

That was a very silly omission from me.

Unfortunately, it was caused by some cut&paste
to tidy up the code before posting.

I did add the RET just now, but the problem remains.


Regards,
Ronald
Regards,
Ronald van Aalst
raalst
 
Posts: 13
Joined: Tue Sep 27, 2005 7:28 pm
Location: netherlands

Postby fpga4fun » Sun Oct 23, 2005 1:33 am

Too bad, would have been an easy one.

Probably a bug in Spoc's handling of subroutines... hopefully I'll have time to work on that soon.
fpga4fun
Site Admin
 
Posts: 837
Joined: Thu Sep 18, 2003 6:47 am

bughunting

Postby raalst » Sun Oct 23, 2005 8:41 am

I'll try to nail down further what the problem is.

I'll report back when I have some more results.
Regards,
Ronald van Aalst
raalst
 
Posts: 13
Joined: Tue Sep 27, 2005 7:28 pm
Location: netherlands

testing HelloWorld

Postby raalst » Sun Oct 23, 2005 10:47 am

Hi, I tested a lot with my own setup. But then I thought of testing HelloWorld.

I ran the hello world succesfully as-is.
Then I moved the JSR call up to just below the SendChar label
causing all output to stop.

After that I tried to recreate the "environment" of the JSR as close as possible (see below) but still no output.

This is only posed for documentation purposes. I am in no hurry,
I hope that Jean or somebody else reacts to this when time permits.

Code: Select all
// Example of spoc processor routine
// This displays periodically the string "Hello world!" on an RS-232 terminal


////
// set the stack pointer (required since we use a subroutine below)
  do #0x0C00 -> SP

Begin:
  do #GreetingString -> CS

SendChar:
  do #0x0000 -> RA7
  jmp.z=1 #continue
  jsr #Delay
  jmp #continue

// delay subroutine
Delay:
  do.dw #200000 -> A
DelayLoop:
  dec.dw A
  jmp.z=1 #DelayLoop
  ret

continue:
  sel CS.p
  do #0x1000 -> WA0
  do.byte @ -> @  // transmit one byte out of RS-232 TX

// check the RS-232 TX busy bit
  do #0x1000 -> RA0
LoopTxD_ready:
  do.bit @
  jmp.z=1 #LoopTxD_ready

// check end of string
  do CS-#GreetingStringEnd
  jmp.z=1 #SendChar

// once string completely sent, delay before sending again
// jsr #Delay
  jmp #Begin

GreetingString:
  data.byte "Hello world!", 13
GreetingStringEnd:

// that's all folks
Regards,
Ronald van Aalst
raalst
 
Posts: 13
Joined: Tue Sep 27, 2005 7:28 pm
Location: netherlands

spoc.v code

Postby raalst » Sun Oct 23, 2005 11:22 am

I have read (not understood ;-) the spoc.v code and I saw several constructs I did not recognize or which struck me as odd.
Maybe they are errors (more likely they are correct and I need to be educated ;-)

nevertheless :

[snippet 1]
reg [3:0] read_opcode_fixedcnt;
wire read_opcode_fixed = state_opcode==3'h0 & (ExecuteOpcode_Enable | |read_opcode_fixedcnt);
>>> here there is a <space> between the two <|> symbols.
>>> I asume they mean to be a OR <||>. is the space legal ?
>>> I could not find the use of <|> documented in QuartusII web
>>> would it be binary-OR ? quartus suggests <#> as an OR symbol
wire read_opcode_fixed_lastbit = (read_opcode_fixedcnt==shift_opcode_length-1);

[snippet 2]
wire WriteData = dataspaceRAM_data;
wire WriteEnable = ExecuteOpcode_CW & DoConditionalUpdates & |WAAI[15:12] & AT_WEN;
>>> a single <|> in front of a register. never seen that before
wire dataspaceRAM_we = ExecuteOpcode_CW & DoConditionalUpdates & ((~|WAAI[15:12] & AT_WEN) | MUX_DBR);
>>> same here
assign ReadAddress = RAAI;

[snippet 3]
wire dataspace_q = (~MUX_DRX & |RAAI[15:12]) ? ReadData :
dataspaceRAM_q;
>>> same here

[snippet 4]
wire ExecuteOpcode_startpipe = ReadOpcode_DoneSoon | |ExecuteOpcode_Cycle;
>>> two <|> with space

[snippet 5]
wire ALU_sumout = ALUA_in ^ ALUB_in ^ FlagC_in;
>>> never seen a <^>, not found in Quartus help,
>>> except as a exponent in arithmetic
Regards,
Ronald van Aalst
raalst
 
Posts: 13
Joined: Tue Sep 27, 2005 7:28 pm
Location: netherlands

Postby fpga4fun » Sun Oct 23, 2005 3:54 pm

A "|" before a register means "OR" all the bits of the register together.
A "&" before a register means "AND" all the bits of the register together.

So the space in snippet 1 is necessary and the meaning is not the same than if there are no space.

The "^" means XOR.

Try to see this page
http://www.fpga4fun.com/VerilogTips.html
It may explain better what I mean.
fpga4fun
Site Admin
 
Posts: 837
Joined: Thu Sep 18, 2003 6:47 am

Postby raalst » Sun Oct 23, 2005 7:33 pm

thanks, Jean
Regards,
Ronald van Aalst
raalst
 
Posts: 13
Joined: Tue Sep 27, 2005 7:28 pm
Location: netherlands


Return to Spoc