Lightweight Debug Unit specifications

289 views
Skip to first unread message

Richard Herveille

unread,
May 17, 2016, 4:14:42 AM5/17/16
to de...@groups.riscv.org
Hi,

I’ve attached the (draft) specifications for a lightweight Debug Unit.
It supports hardware break/watchpoints, single stepping, and simple branch tracing.
It’s easy to implement and small. It’s been tested and is working together with the adv_dbg_sys with support for GDB and Eclipse.

Comments and suggestions are welcomed,
Richard

RISCV_DebugUnit_specifications_rev0.1.pdf

Ronan BARZIC

unread,
May 18, 2016, 2:47:30 AM5/18/16
to RISC-V Debug Group
Hi Richard,

Very nice work !
Do you have a freely available implementation of your debug system, specially the gdb part ?  I was trying to build a similar system using adv_debug_sys as the debug interface for my own Risc-V implementation (https://github.com/rbarzic/nanorv32) , not adv_dbg_sys. But  I didn't had time to complete it yet. My idea was to map the debug registers in the CPU address space, like the Cortex-M  so that the debug interface is just another bus master.

Ronan

Stefan Wallentowitz

unread,
May 18, 2016, 2:53:14 AM5/18/16
to de...@groups.riscv.org
On 18.05.2016 08:47, Ronan BARZIC wrote:
> Hi Richard,
>
> Very nice work !
> Do you have a freely available implementation of your debug system,
> specially the gdb part ? I was trying to build a similar system using
> adv_debug_sys as the debug interface for my own Risc-V implementation
> (https://github.com/rbarzic/nanorv32) , not adv_dbg_sys. But I didn't
> had time to complete it yet. My idea was to map the debug registers in
> the CPU address space, like the Cortex-M so that the debug interface is
> just another bus master.
>
> Ronan

Hi Ronan,

thats great to hear. The guys from the Pulp project (are planning to)
use it similarly. Only a thin extra layer is needed to encapsulate the
stall register, I think. Would be great if you can share your progress.

Richard's code can be found on Github: https://github.com/RoaLogic

Best,
Stefan


signature.asc

Monte

unread,
May 18, 2016, 1:43:56 PM5/18/16
to RISC-V Debug Group
A few questions/comments

The bit and register assignments inherently limit the number of maskable interrupts. I would rather see the interrupt enable/cause bits for maskable
interrupts in separate registers, with space left in the register addressing for more interrupts. I am working on a RISC-V design that allows up to 128
maskable interrupts.

Is there any utility to allowing a breakpoint to be set on a particular CSR access?

Should there be control bits (perhaps in DBG_CTRL) to control disabling counters and timers?

Monte

Ray Van De Walker

unread,
May 18, 2016, 2:09:02 PM5/18/16
to de...@groups.riscv.org

I think trapping accesses to a CSR is a luxury.

Many effective debuggers don’t trap data accesses at all.

 

We all expect counters and timers to run the same with and without debugging.

One of the most unpleasant weeks I’ve ever spent was trying to find

a 3% timing error caused by a debugger that periodically halted timer clocks.

And, I never did find the issue myself;  Fortunately I had access to the designer.

The designer made a lucky guess about what the problem was,

told me about the issue, and where it was documented.

--
You received this message because you are subscribed to the Google Groups "RISC-V Debug Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to debug+un...@groups.riscv.org.
To post to this group, send email to de...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/debug/.
To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/debug/4aae2efc-a1bb-4156-8da5-81d297b3c634%40groups.riscv.org.

Stefan Wallentowitz

unread,
May 18, 2016, 2:13:50 PM5/18/16
to de...@groups.riscv.org
On 18.05.2016 20:08, Ray Van De Walker wrote:
> I think trapping accesses to a CSR is a luxury.
>
> Many effective debuggers don’t trap data accesses at all.
>
>
>
> We all expect counters and timers to run the same with and without
> debugging.
>
> One of the most unpleasant weeks I’ve ever spent was trying to find
>
> a 3% timing error caused by a debugger that periodically halted timer
> clocks.
>
> And, I never did find the issue myself; Fortunately I had access to the
> designer.
>
> The designer made a lucky guess about what the problem was,
>
> told me about the issue, and where it was documented.
>

Anyways I am wondering if it is worth the effort to add such features
marked optional and to add a feature present register. Any opinions?

Cheers,
Stefan


signature.asc

Richard Herveille

unread,
May 18, 2016, 3:57:07 PM5/18/16
to Monte, RISC-V Debug Group


Sent from my iPad

On 18 mei 2016, at 19:44, Monte <mon...@systemyde.com> wrote:

A few questions/comments

The bit and register assignments inherently limit the number of maskable interrupts. I would rather see the interrupt enable/cause bits for maskable
interrupts in separate registers, with space left in the register addressing for more interrupts. I am working on a RISC-V design that allows up to 128
maskable interrupts.

Currently XLEN is limited to 32/64bits. My assumption was that more interrupts would be handled by an external PIC.  At least that's how I handle them. 
Handling masks for such amounts of interrupts always requires multiple registers. There are plenty addresses available in the debug space. 
I'll add it as a request. 


Is there any utility to allowing a breakpoint to be set on a particular CSR access?

That would be a watch point specific for CSR access. Is that really useful?


Should there be control bits (perhaps in DBG_CTRL) to control disabling counters and timers?

Normally counters keep running, even in debug mode. Is there a particular reason why you would want to stop any counters?

Richard



Monte



On Tuesday, May 17, 2016 at 1:14:42 AM UTC-7, Richard Herveille wrote:
Hi,

I’ve attached the (draft) specifications for a lightweight Debug Unit.
It supports hardware break/watchpoints, single stepping, and simple branch tracing.
It’s easy to implement and small. It’s been tested and is working together with the adv_dbg_sys with support for GDB and Eclipse.

Comments and suggestions are welcomed,
Richard

Richard Herveille

unread,
May 18, 2016, 4:00:06 PM5/18/16
to Stefan Wallentowitz, de...@groups.riscv.org
The breakpoints already present themselves; bit0=1 is feature present, bit0=0 feature is absent. To be consistent I would prefer the same approach.

Richard



>
> Cheers,
> Stefan
>
>
> --
> You received this message because you are subscribed to the Google Groups "RISC-V Debug Group" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to debug+un...@groups.riscv.org.
> To post to this group, send email to de...@groups.riscv.org.
> Visit this group at https://groups.google.com/a/groups.riscv.org/group/debug/.
> To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/debug/573CB0DB.1070202%40wallentowitz.de.

Richard Herveille

unread,
May 31, 2016, 3:26:54 AM5/31/16
to de...@groups.riscv.org, Richard Herveille, Stefan Wallentowitz


When the debug unit is used with a CPU with caches, then changing memory contents (like GDB does for software breakpoints) may fail.
Does it make sense to add cache-flush and/or cache-enable bits to the specifications? The function of cache-flush would be similar to the FENCE_I instruction. And the cache-enable bits simply enable/disable the cache functionality.

Richard

ROA LOGIC
Design Services and Silicon Proven IP

Richard Herveille
Managing Director
Cell +31 (6) 5207 2230



Stefan Wallentowitz

unread,
Jun 14, 2016, 11:32:57 AM6/14/16
to de...@groups.riscv.org
Hi Richard,

I discussed the spec with an expert and got some feedback:

1. For flexible integration it may be better to have the combinational
path from dbg_bp to dbg_stall configurable inside the debug unit.
Essentially this would be another register bit in DBG_CTRL:

bit 2: sob (stall-on-breakpoint). When asserted the debug unit stalls
the core. Reset value is 0.

Justification: It adds a register bit, an AND and an OR to the logic
(cpu_stall = dbg_stall | (sob & bp), but it can be used as a simple bus
interface without extra logic needed to drive the stall pin.

2. Along the same lines it may be useful to add another bit to stall via
the bus interface in DBG_CTRL:

bit 3: stall. When asserted stalls the core. Reset value is 0.

Justification: It adds a register bit and another OR to the logic
(cpu_stall = dbg_stall | (sob & bp) | stall). It allows for asynchronous
stalls via the bus interface.

3. A signal named dbg_stall_ack may be useful for trace (cross-trigger)
logic. It is asserted by the core once the stall effectively took place.

4. Why do NOPs not emit a single step trace? They are pretty rare and
its actual information getting lost.

5. Is NPC and PC still used for RISC-V? If so can you clarify the
meaning and what the state of the CPU must be, e.g., if the PC of the
breakpoint must not have fully executed (which can be troublesome for
memory watchpoints, but is better for debug).

Cheers,
Stefan

signature.asc

Richard Herveille

unread,
Jun 14, 2016, 1:53:16 PM6/14/16
to Stefan Wallentowitz, Richard Herveille, de...@groups.riscv.org
Hi Stefan,

See my comments below …


> 1. For flexible integration it may be better to have the combinational
> path from dbg_bp to dbg_stall configurable inside the debug unit.
> Essentially this would be another register bit in DBG_CTRL:
>
> bit 2: sob (stall-on-breakpoint). When asserted the debug unit stalls
> the core. Reset value is 0.
>
> Justification: It adds a register bit, an AND and an OR to the logic
> (cpu_stall = dbg_stall | (sob & bp), but it can be used as a simple bus
> interface without extra logic needed to drive the stall pin.

This would be like a master break-point enable.
The same can be achieved by enabling/disabling the individual breakpoints.
When I look at the commands GDB’s RSP generates, then this bit would never be used.


> 2. Along the same lines it may be useful to add another bit to stall via
> the bus interface in DBG_CTRL:
>
> bit 3: stall. When asserted stalls the core. Reset value is 0.
>
> Justification: It adds a register bit and another OR to the logic
> (cpu_stall = dbg_stall | (sob & bp) | stall). It allows for asynchronous
> stalls via the bus interface.

Currently this is implemented outside the debug unit.
The adv_dbg_sys (or any other debug controller) will have it’s own control registers.
GDB uses this, for example, to initially stall the CPU.


> 3. A signal named dbg_stall_ack may be useful for trace (cross-trigger)
> logic. It is asserted by the core once the stall effectively took place.

This is already implemented, though slightly different.
dbg_bp_o is asserted when a breakpoint hit. As a result dbg_stall_i must be asserted immediately.


> 4. Why do NOPs not emit a single step trace? They are pretty rare and
> its actual information getting lost.

True, but many CPUs insert bubbles (NOPs) in the pipe during a stall or to clean the pipe (after a stall).
Hitting on NOPs may cause false triggers.


> 5. Is NPC and PC still used for RISC-V? If so can you clarify the
> meaning and what the state of the CPU must be, e.g., if the PC of the
> breakpoint must not have fully executed (which can be troublesome for
> memory watchpoints, but is better for debug).

I currently implemented both. Not sure how useful both are though …

Richard




>
> Cheers,
> Stefan
>
> --
> You received this message because you are subscribed to the Google Groups "RISC-V Debug Group" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to debug+un...@groups.riscv.org.
> To post to this group, send email to de...@groups.riscv.org.
> Visit this group at https://groups.google.com/a/groups.riscv.org/group/debug/.
> To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/debug/576023A6.2020603%40wallentowitz.de.

Stefan Wallentowitz

unread,
Jun 15, 2016, 5:36:00 AM6/15/16
to de...@groups.riscv.org
On 14.06.2016 19:53, Richard Herveille wrote:
> Hi Stefan,
>
> See my comments below …

Thanks a lot, Richard!

>
>> 1. For flexible integration it may be better to have the combinational
>> path from dbg_bp to dbg_stall configurable inside the debug unit.
>> Essentially this would be another register bit in DBG_CTRL:
>>
>> bit 2: sob (stall-on-breakpoint). When asserted the debug unit stalls
>> the core. Reset value is 0.
>>
>> Justification: It adds a register bit, an AND and an OR to the logic
>> (cpu_stall = dbg_stall | (sob & bp), but it can be used as a simple bus
>> interface without extra logic needed to drive the stall pin.
>
> This would be like a master break-point enable.
> The same can be achieved by enabling/disabling the individual breakpoints.
> When I look at the commands GDB’s RSP generates, then this bit would never be used.

Yes, but I am thinking about a more generic use, such as really
attaching the MMIO interface to a bus. Then any extra wrapper logic may
already be obsolete by providing access to this functionality in the
register map.

>> 2. Along the same lines it may be useful to add another bit to stall via
>> the bus interface in DBG_CTRL:
>>
>> bit 3: stall. When asserted stalls the core. Reset value is 0.
>>
>> Justification: It adds a register bit and another OR to the logic
>> (cpu_stall = dbg_stall | (sob & bp) | stall). It allows for asynchronous
>> stalls via the bus interface.
>
> Currently this is implemented outside the debug unit.
> The adv_dbg_sys (or any other debug controller) will have it’s own control registers.
> GDB uses this, for example, to initially stall the CPU.

I agree, but adding it wouldn't harm this solution, right?

>> 3. A signal named dbg_stall_ack may be useful for trace (cross-trigger)
>> logic. It is asserted by the core once the stall effectively took place.
>
> This is already implemented, though slightly different.
> dbg_bp_o is asserted when a breakpoint hit. As a result dbg_stall_i must be asserted immediately.

Yes, but in case of an asynchronous stall by the debug controller it can
take several cycles to actually halt the pipeline, right?

>> 4. Why do NOPs not emit a single step trace? They are pretty rare and
>> its actual information getting lost.
>
> True, but many CPUs insert bubbles (NOPs) in the pipe during a stall or to clean the pipe (after a stall).
> Hitting on NOPs may cause false triggers.

I see. From an implementation standpoint, would it be too complicated to
mark bubbles in the pipeline? The bubbles probably don't have a valid PC
anyways. I was told by a debugging tool guy, that missing out a taken
instruction can lead to many issues.

>> 5. Is NPC and PC still used for RISC-V? If so can you clarify the
>> meaning and what the state of the CPU must be, e.g., if the PC of the
>> breakpoint must not have fully executed (which can be troublesome for
>> memory watchpoints, but is better for debug).
>
> I currently implemented both. Not sure how useful both are though …

Okay I see. How is it in your implementation, is the instruction at PC
already executed or not started? I think it should be defined. NPC
probably only makes sense if PC was executed, right?

Cheers,
Stefan

signature.asc

Richard Herveille

unread,
Jun 15, 2016, 6:17:37 AM6/15/16
to Stefan Wallentowitz, Richard Herveille, de...@groups.riscv.org
Hi Stefan,


1. For flexible integration it may be better to have the combinational
path from dbg_bp to dbg_stall configurable inside the debug unit.
Essentially this would be another register bit in DBG_CTRL:

bit 2: sob (stall-on-breakpoint). When asserted the debug unit stalls
the core. Reset value is 0.

Justification: It adds a register bit, an AND and an OR to the logic
(cpu_stall = dbg_stall | (sob & bp), but it can be used as a simple bus
interface without extra logic needed to drive the stall pin.

This would be like a master break-point enable.
The same can be achieved by enabling/disabling the individual breakpoints.
When I look at the commands GDB’s RSP generates, then this bit would never be used.

Yes, but I am thinking about a more generic use, such as really
attaching the MMIO interface to a bus. Then any extra wrapper logic may
already be obsolete by providing access to this functionality in the
register map.

Sure, can be done …



2. Along the same lines it may be useful to add another bit to stall via
the bus interface in DBG_CTRL:

bit 3: stall. When asserted stalls the core. Reset value is 0.

Justification: It adds a register bit and another OR to the logic
(cpu_stall = dbg_stall | (sob & bp) | stall). It allows for asynchronous
stalls via the bus interface.

Currently this is implemented outside the debug unit.
The adv_dbg_sys (or any other debug controller) will have it’s own control registers.
GDB uses this, for example, to initially stall the CPU.

I agree, but adding it wouldn't harm this solution, right?

Agreed … it wouldn’t.




3. A signal named dbg_stall_ack may be useful for trace (cross-trigger)
logic. It is asserted by the core once the stall effectively took place.

This is already implemented, though slightly different.
dbg_bp_o is asserted when a breakpoint hit. As a result dbg_stall_i must be asserted immediately. 

Yes, but in case of an asynchronous stall by the debug controller it can
take several cycles to actually halt the pipeline, right?

Actually it should not :-)
When dbg_bp_o is asserted, then dbg_stall_i must be asserted immediately (combinatorial).
Now this could be moved into the stall bit you mention above.
The entire debug_controller internal register becomes superfluous then and can be removed.



4. Why do NOPs not emit a single step trace? They are pretty rare and
its actual information getting lost.

True, but many CPUs insert bubbles (NOPs) in the pipe during a stall or to clean the pipe (after a stall).
Hitting on NOPs may cause false triggers.

I see. From an implementation standpoint, would it be too complicated to
mark bubbles in the pipeline? The bubbles probably don't have a valid PC
anyways. I was told by a debugging tool guy, that missing out a taken
instruction can lead to many issues.

Sure … bubbles could be marked …




5. Is NPC and PC still used for RISC-V? If so can you clarify the
meaning and what the state of the CPU must be, e.g., if the PC of the
breakpoint must not have fully executed (which can be troublesome for
memory watchpoints, but is better for debug).

I currently implemented both. Not sure how useful both are though …

Okay I see. How is it in your implementation, is the instruction at PC
already executed or not started? I think it should be defined. NPC
probably only makes sense if PC was executed, right?

Currently the CPU triggers a breakpoint when the instruction @PC is about to execute (so not yet executed). NPC points to the next instruction. Could make sense when the instruction is a branch or similar.

Watchpoints are triggered after the memory access completed.


Richard




Tom van Leeuwen

unread,
Jul 1, 2016, 10:55:21 AM7/1/16
to de...@groups.riscv.org
On 14-06-16 17:32, Stefan Wallentowitz wrote:
Hi Richard,

I discussed the spec with an expert and got some feedback:

1. For flexible integration it may be better to have the combinational
path from dbg_bp to dbg_stall configurable inside the debug unit.
Essentially this would be another register bit in DBG_CTRL:

bit 2: sob (stall-on-breakpoint). When asserted the debug unit stalls
the core. Reset value is 0.

Justification: It adds a register bit, an AND and an OR to the logic
(cpu_stall = dbg_stall | (sob & bp), but it can be used as a simple bus
interface without extra logic needed to drive the stall pin.
Hi Stefan / Richard,

Thanks for the work on the debug specification,

I am also working on a debug-interface for our Risc-V implementation, and I like the idea of making the debug unit a pure MMIO interface.
I see no point in having an extra 'debug controller' outside the core that only conditionally copies the dbg_bp to the dbg_stall signal (apart from translating JTAG commands to register writes, which is a more general problem)

However, when using just the proposed 'stall-on-breakpoint' bit, I wonder how would one be able to continue once the breakpoint is reached? One could set it to 'sob' to 0 and then back to 1, but in that case one would miss the next breakpoint, especially when single-stepping.

In general, it is unclear to me from the specifications how the dbg_bp signal works and how one would execute the Single-Step trace, even using the originally proposed interface. If dbg_stall is de-asserted, a few things can happen during the next clock cycle, depending on the implementation:

1) dbg_bp was already low since it is only asserted for one clock cycle anyway (?)
2) dbg_bp goes low because the next instruction is being fetched but it is not yet executed
3) dbg_bp is still high because the core is still idle (maybe a certain implementation is slow to 'resume')
4) dbg_bp is again high because the next Single-Step breakpoint is reached
Obviously 3 and 4 cannot be distinguished, but in 3), the debug unit shall not stall the core while in 4) it shall be stalled.

To avoid the ambiguity, you could specify that dbg_bp shall always go low the next clock cycle if dbg_stall is made low low (unless a new breakpoint is reached), or specify that dbg_bp is only high for one clock cycle anyway.
Can you elaborate on what the intended behavior of dbg_bp is?

In either case, I propose to add another bit to the register as follows:

bit 3: cont (Continue after breakpoint). When a '1' is written and the core
is stalled using the 'sob' bit, the debug unit allows the core to continue
until next breakpoint is reached. This bit will be cleared automatically in
the next clock cycle.

I look forward to your comments,

With kind regards,
Tom van Leeuwen  System Designer
 
A Burgemeester Jamessingel 1, P.O. Box 2013, 2800 BD Gouda, The Netherlands | W technolution.com
 
This e-mail is intended exclusively for the addressee(s), and may not be passed on to, or made available for use by any person other than the addressee(s). Technolution B.V. rules out any and every liability resulting from any electronic transmission.

Richard Herveille

unread,
Jul 3, 2016, 3:05:10 AM7/3/16
to Tom van Leeuwen, Richard Herveille, de...@groups.riscv.org
Hi Tom,



Hi Richard,

I discussed the spec with an expert and got some feedback:

1. For flexible integration it may be better to have the combinational
path from dbg_bp to dbg_stall configurable inside the debug unit.
Essentially this would be another register bit in DBG_CTRL:

bit 2: sob (stall-on-breakpoint). When asserted the debug unit stalls
the core. Reset value is 0.

Justification: It adds a register bit, an AND and an OR to the logic
(cpu_stall = dbg_stall | (sob & bp), but it can be used as a simple bus
interface without extra logic needed to drive the stall pin.
Hi Stefan / Richard,

Thanks for the work on the debug specification,

I am also working on a debug-interface for our Risc-V implementation, and I like the idea of making the debug unit a pure MMIO interface.
I see no point in having an extra 'debug controller' outside the core that only conditionally copies the dbg_bp to the dbg_stall signal (apart from translating JTAG commands to register writes, which is a more general problem)

Currently my implementation of the adv_dbg_sys does just that; it copies dbp_bp to dbg_stall. And I agree, there is very little argument for doing so. That functionality can (and probably should) be moved into the Debug Unit.



However, when using just the proposed 'stall-on-breakpoint' bit, I wonder how would one be able to continue once the breakpoint is reached? One could set it to 'sob' to 0 and then back to 1, but in that case one would miss the next breakpoint, especially when single-stepping.

In general, it is unclear to me from the specifications how the dbg_bp signal works and how one would execute the Single-Step trace, even using the originally proposed interface. If dbg_stall is de-asserted, a few things can happen during the next clock cycle, depending on the implementation:

1) dbg_bp was already low since it is only asserted for one clock cycle anyway (?)
2) dbg_bp goes low because the next instruction is being fetched but it is not yet executed
3) dbg_bp is still high because the core is still idle (maybe a certain implementation is slow to 'resume')
4) dbg_bp is again high because the next Single-Step breakpoint is reached
Obviously 3 and 4 cannot be distinguished, but in 3), the debug unit shall not stall the core while in 4) it shall be stalled.

To avoid the ambiguity, you could specify that dbg_bp shall always go low the next clock cycle if dbg_stall is made low low (unless a new breakpoint is reached), or specify that dbg_bp is only high for one clock cycle anyway.
Can you elaborate on what the intended behavior of dbg_bp is?

In either case, I propose to add another bit to the register as follows:

bit 3: cont (Continue after breakpoint). When a '1' is written and the core
is stalled using the 'sob' bit, the debug unit allows the core to continue
until next breakpoint is reached. This bit will be cleared automatically in
the next clock cycle.


There is no need for the Continue-after-breakpoint bit.
The dbg_bp signal is a strobe signal; it is asserted for only 1 clock cycle. In my implementation that means taking into account memory and pipeline stalls.
When dbg_bp is asserted it causes dbg_stall to be asserted in the same cycle (so combinatorial). That causes the CPU to stall; depending on the implementation anything from ID and above. Any instruction in the execute phase should complete.
When the JTAG (or other interface) controller set dbg_stall to ‘0’, the CPU continues. Causing the current instruction to enter the execute phase and new instructions to be loaded. For single-stepping this means the CPU stalls immediately again, but since the previous instruction entered the execute phase, it will complete.

Richard




I look forward to your comments,

With kind regards,
Tom van Leeuwen  System Designer
 
A Burgemeester Jamessingel 1, P.O. Box 2013, 2800 BD Gouda, The Netherlands | W technolution.com
 
This e-mail is intended exclusively for the addressee(s), and may not be passed on to, or made available for use by any person other than the addressee(s). Technolution B.V. rules out any and every liability resulting from any electronic transmission.

--
You received this message because you are subscribed to the Google Groups "RISC-V Debug Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to debug+un...@groups.riscv.org.
To post to this group, send email to de...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/debug/.

Tom van Leeuwen

unread,
Jul 4, 2016, 4:02:52 AM7/4/16
to Richard Herveille, de...@groups.riscv.org
Hi Richard,

On 03-07-16 09:05, Richard Herveille wrote:
Hi Tom,

(...)

There is no need for the Continue-after-breakpoint bit.
The dbg_bp signal is a strobe signal; it is asserted for only 1 clock cycle. In my implementation that means taking into account memory and pipeline stalls.
When dbg_bp is asserted it causes dbg_stall to be asserted in the same cycle (so combinatorial). That causes the CPU to stall; depending on the implementation anything from ID and above. Any instruction in the execute phase should complete.
When the JTAG (or other interface) controller set dbg_stall to ‘0’, the CPU continues. Causing the current instruction to enter the execute phase and new instructions to be loaded. For single-stepping this means the CPU stalls immediately again, but since the previous instruction entered the execute phase, it will complete.

Thanks for your reply, it is now clear to me how the dbg_bp signal works. Maybe you can clarify in the specifications document that dbg_bp is a strobe signal?
However, I think we are still confusing two different situations in the conversation.

Situation A is with the dbg_bp and dbg_stall signals controlled by adv_dbg_sys, and situation B is using only the register interface.

In case of situation A, we don't need a 'continue' signal since dbg_bp is a strobe signal, and we can simply assert stall as long as we don't want to continue. The original implementation as proposed in v0.1 can do this.
In case of situation B, with the proposed 'stall-on-breakpoint' register bit, I think we do need a way to continue using a register bit, and de-asserting 'stall-on-breakpoint' results in missing the next breakpoint(s). Or am I missing something?
(Optionally we can combine the two register bits, thus when a '1' is written in 'stall-on-breakpoint' when it is already stalled on a breakpoint, it will issue a continue.)

Maybe Stefan can clarify how he intended the 'stall-on-breakpoint' bit to be implemented w.r.t single stepping?

Thanks,

Tom

Richard Herveille

unread,
Jul 4, 2016, 4:11:29 AM7/4/16
to Tom van Leeuwen, Richard Herveille, de...@groups.riscv.org
Hi Tom,


On 04 Jul 2016, at 10:02, Tom van Leeuwen <tom.van...@technolution.eu> wrote:

Hi Richard,

On 03-07-16 09:05, Richard Herveille wrote:
Hi Tom,

(...)

There is no need for the Continue-after-breakpoint bit.
The dbg_bp signal is a strobe signal; it is asserted for only 1 clock cycle. In my implementation that means taking into account memory and pipeline stalls.
When dbg_bp is asserted it causes dbg_stall to be asserted in the same cycle (so combinatorial). That causes the CPU to stall; depending on the implementation anything from ID and above. Any instruction in the execute phase should complete.
When the JTAG (or other interface) controller set dbg_stall to ‘0’, the CPU continues. Causing the current instruction to enter the execute phase and new instructions to be loaded. For single-stepping this means the CPU stalls immediately again, but since the previous instruction entered the execute phase, it will complete.

Thanks for your reply, it is now clear to me how the dbg_bp signal works. Maybe you can clarify in the specifications document that dbg_bp is a strobe signal?
However, I think we are still confusing two different situations in the conversation.

Situation A is with the dbg_bp and dbg_stall signals controlled by adv_dbg_sys, and situation B is using only the register interface.

In case of situation A, we don't need a 'continue' signal since dbg_bp is a strobe signal, and we can simply assert stall as long as we don't want to continue. The original implementation as proposed in v0.1 can do this.
In case of situation B, with the proposed 'stall-on-breakpoint' register bit, I think we do need a way to continue using a register bit, and de-asserting 'stall-on-breakpoint' results in missing the next breakpoint(s). Or am I missing something?
(Optionally we can combine the two register bits, thus when a '1' is written in 'stall-on-breakpoint' when it is already stalled on a breakpoint, it will issue a continue.)

Maybe Stefan can clarify how he intended the 'stall-on-breakpoint' bit to be implemented w.r.t single stepping?


I think Stefan should elaborate. I haven’t had any time yet to dive into the requests and update the proposed spec. However I will throw in my 2 cents anyways;
- I see hardware breakpoints and single stepping as two different events
- Therefore ‘stall-on-breakpoint’ could be used to gate off all/any hardware breakpoint. I am not sure how useful this is, as one can simple disable the ‘enable’ bit on the hardware breakpoint registers. That has the same effect and simplifies the implementation. Stefan, can you please elaborate on this?
- Single-stepping is NOT considered a hardware breakpoint and hence would not be affected by the ‘stall-on-breakpoint’ bit.


Another addition I think is required is a way to reset the thread. I’ve seen threads getting locked because they wait on external accesses, which may never come. Having a means of reseting the thread solves this.

Richard



Thanks,

Tom

Richard Herveille

unread,
Nov 28, 2016, 9:55:08 AM11/28/16
to de...@groups.riscv.org, Richard Herveille
Hi all,

I finally found some time to update the specifications and add features requested by the community.

Richard

RISCV_DebugUnit_specifications_rev0.2.pdf

Stefan Wallentowitz

unread,
Nov 28, 2016, 10:10:16 AM11/28/16
to de...@groups.riscv.org
On 28.11.2016 15:54, Richard Herveille wrote:
> Hi all,
>
> I finally found some time to update the specifications and add features
> requested by the community.
>
> Richard
>

Hi Richard,

just a very minor remark. On page 4 I suppose it is

Int reg: 0x100-0x11f
reserved: 0x120-13f
FRF: 0x140-0x15f
FRF(ext): 0x160-0x17f
reserved: 0x180-0x7ff

Cheers,
Stefan


signature.asc

Richard Herveille

unread,
Nov 28, 2016, 10:18:27 AM11/28/16
to Stefan Wallentowitz, RISC-V Debug Group, Richard Herveille
Doh! Yes. Fixed in my local revision. If no immediate comments are provided I will sent out an updated release in a few hours.

Richard


ROA LOGIC
Design Services and Silicon Proven IP

Richard Herveille
Managing Director
Cell +31 (6) 5207 2230




--
You received this message because you are subscribed to the Google Groups "RISC-V Debug Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to debug+un...@groups.riscv.org.
To post to this group, send email to de...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/debug/.

Tim Newsome

unread,
Nov 29, 2016, 3:20:02 PM11/29/16
to Richard Herveille, de...@groups.riscv.org
Hi Richard,

I still don't see how arbitrary instructions will be executed, although that is listed in the comparison document. Did I miss it?

Tim

--
You received this message because you are subscribed to the Google Groups "RISC-V Debug Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to debug+unsubscribe@groups.riscv.org.

To post to this group, send email to de...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/debug/.

Richard Herveille

unread,
Nov 29, 2016, 3:56:56 PM11/29/16
to Tim Newsome, de...@groups.riscv.org
Ah yes, it's not in the spec. 
I will add it as an option. Basically you just write the opcode to a register and tell the Debug Unit to execute it; either by setting a bit in the BP_CTRL register or by executing upon each write to the register, whichever has the preference of the group. 


Richard 


Sent from my iPad

Tim Newsome

unread,
Nov 29, 2016, 5:52:53 PM11/29/16
to Richard Herveille, de...@groups.riscv.org
That makes sense. (It's limited to 32 bit opcodes, I assume, but that seems fair enough, although eventually we'll need a mechanism for arbitrary instructions.) I'm wondering if it's possible to get rid of eg. the CSR and GPR access methods if you have a mechanism to execute those arbitrary instructions. Or maybe only x1 needs to be accessible, or something like that.

Tim

On Tue, Nov 29, 2016 at 12:56 PM, Richard Herveille <richard....@roalogic.com> wrote:
Ah yes, it's not in the spec. 
I will add it as an option. Basically you just write the opcode to a register and tell the Debug Unit to execute it; either by setting a bit in the BP_CTRL register or by executing upon each write to the register, whichever has the preference of the group. 


Richard 


Sent from my iPad

On 29 Nov 2016, at 21:20, Tim Newsome <t...@sifive.com> wrote:

Hi Richard,

I still don't see how arbitrary instructions will be executed, although that is listed in the comparison document. Did I miss it?

Tim
On Mon, Nov 28, 2016 at 6:54 AM, Richard Herveille <richard.herveille@roalogic.com> wrote:
Hi all,

I finally found some time to update the specifications and add features requested by the community.

Richard


ROA LOGIC
Design Services and Silicon Proven IP

Richard Herveille
Managing Director
Cell +31 (6) 5207 2230



--
You received this message because you are subscribed to the Google Groups "RISC-V Debug Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to debug+un...@groups.riscv.org.
Reply all
Reply to author
Forward
0 new messages