On Sun, May 20, 2012 at 10:54 PM, Julius Baxter <[email protected]> wrote:
> On Sun, May 20, 2012 at 2:35 PM, Julius Baxter <[email protected]> wrote:
>> On Sat, May 19, 2012 at 11:24 PM, Matthew Hicks <[email protected]> wrote:
>>> From my experiences with hardware that can handle illegal instruction
>>> exceptions occuring every 3 instructions:
>>>
>>> epcr <= ex_dslot ? wb_pc : delayed_ex_dslot ? dl_pc : ex_pc;
>>>
>>
>> Yes, that is exactly what I needed in the end.
>>
>> I've got a test for the appropriate behaviour of the range exception
>> on arithmetic operations including in delay slot. The following patch
>> to or1200_except was what is needed:
>>
>> @@ -571,26 +585,30 @@
>>                       except_type <=  `OR1200_EXCEPT_RANGE;
>>                       epcr <=  ex_dslot ?
>>                               wb_pc : delayed1_ex_dslot ?
>> -                              id_pc : delayed2_ex_dslot ?
>> -                              id_pc : id_pc;
>> +                              dl_pc : delayed2_ex_dslot ?
>> +                              id_pc : ex_pc;
>>
>>
>> I'm not sure if we really need that delayed2_ex_dslot stuff. I didn't
>> see it asserted during any of the tests I ran.
>>
>> Cheers
>>
>> Julius
>
>
> The following is the full patch I propose for bug 90 for ORPSoC.
> http://bugzilla.opencores.org/bugzilla4/show_bug.cgi?id=90
>
> I'll also make the equivalent fix in the OR1200.
>
>
> Index: rtl/verilog/or1200/or1200_except.v
> ===================================================================
> --- rtl/verilog/or1200/or1200_except.v  (revision 800)
> +++ rtl/verilog/or1200/or1200_except.v  (working copy)
> @@ -571,8 +571,8 @@
>                       except_type <=  `OR1200_EXCEPT_RANGE;
>                       epcr <=  ex_dslot ?
>                               wb_pc : delayed1_ex_dslot ?
> -                              id_pc : delayed2_ex_dslot ?
> -                              id_pc : id_pc;
> +                              dl_pc : delayed2_ex_dslot ?
> +                              id_pc : ex_pc;
>                    end
>  `endif
>  `ifdef OR1200_EXCEPT_FLOAT
> Index: sim/bin/Makefile
> ===================================================================
> --- sim/bin/Makefile    (revision 800)
> +++ sim/bin/Makefile    (working copy)
> @@ -62,6 +62,7 @@
>        or1200-float \
>        or1200-mmu  \
>        or1200-except \
> +       or1200-range \
>        or1200-mac \
>        or1200-ext \
>        or1200-cy       \
> Index: sw/tests/or1200/sim/or1200-range.S
> ===================================================================
> --- sw/tests/or1200/sim/or1200-range.S  (revision 0)
> +++ sw/tests/or1200/sim/or1200-range.S  (revision 0)
> @@ -0,0 +1,175 @@
> +/*
> +       OR1200 Range exception test
> +
> +       Very basic, testing, checking that the EPC value is correct
> +       for generated range exceptions.
> +
> +       Julius Baxter <[email protected]>
> +
> +*/
> +//////////////////////////////////////////////////////////////////////
> +////                                                              ////
> +//// Copyright (C) 2012 Authors and OPENCORES.ORG                 ////
> +////                                                              ////
> +//// This source file may be used and distributed without         ////
> +//// restriction provided that this copyright statement is not    ////
> +//// removed from the file and that any derivative work contains  ////
> +//// the original copyright notice and the associated disclaimer. ////
> +////                                                              ////
> +//// This source file is free software; you can redistribute it   ////
> +//// and/or modify it under the terms of the GNU Lesser General   ////
> +//// Public License as published by the Free Software Foundation; ////
> +//// either version 2.1 of the License, or (at your option) any   ////
> +//// later version.                                               ////
> +////                                                              ////
> +//// This source is distributed in the hope that it will be       ////
> +//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
> +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
> +//// PURPOSE.  See the GNU Lesser General Public License for more ////
> +//// details.                                                     ////
> +////                                                              ////
> +//// You should have received a copy of the GNU Lesser General    ////
> +//// Public License along with this source; if not, download it   ////
> +//// from http://www.opencores.org/lgpl.shtml                     ////
> +////                                                              ////
> +//////////////////////////////////////////////////////////////////////
> +#include "spr-defs.h"
> +#include "board.h"
> +#include "or1200-defines.h"
> +
> +/* =================================================== [ exceptions ] === */
> +       .section .vectors, "ax"
> +
> +
> +/* ---[ 0x100: RESET exception ]----------------------------------------- */
> +        .org 0x100
> +       l.movhi r0, 0
> +       /* Clear status register */
> +       l.ori   r1, r0, SPR_SR_SM
> +       l.mtspr r0, r1, SPR_SR
> +       /* Clear timer  */
> +       l.mtspr r0, r0, SPR_TTMR
> +       /* Init the stack */
> +       .global stack
> +       l.movhi r1, hi(stack)
> +       l.ori   r1, r1, lo(stack)
> +       l.addi  r2, r0, -3
> +       l.and   r1, r1, r2
> +       // Clear r10 -used to remember if we've run the
> +       // test with cache eanbeld yet.
> +       l.movhi r10, 0
> +       /* Jump to program initialisation code */
> +       .global _start
> +       l.movhi r4, hi(_start)
> +       l.ori   r4, r4, lo(_start)
> +       l.jr    r4
> +       l.nop
> +
> +/* ---[ 0x700: ILLEGAL INSN exception ]------------------------------------- 
> */
> +       .org 0x700
> +       l.nop 0x1
> +
> +
> +/* ---[ 0xB00: RANGE exception ]-------------------------------------------- 
> */
> +       .org 0xb00
> +       l.mfspr r3,r0,SPR_EPCR_BASE
> +       l.nop   2
> +       // Check the PC
> +       l.ori   r6,r0,0x7fff // Use this as a mask for the PC
> +       l.and   r7,r6,r3 // just take the bottom 15 bits, should be enough
> +       // Test 1 should be at
> +       l.sfeqi r5,1
> +       l.bf    test1
> +       l.nop
> +       l.sfeqi r5,2
> +       l.bf    test2
> +       l.nop
> +
> +test1:
> +       l.sfnei r7,0xf08 // test 1 trigger insn PC
> +       l.bf    fail
> +       l.nop
> +       // set the PC to step over the range exception
> +       l.addi  r3,r3,4
> +       l.mtspr r0,r3,SPR_EPCR_BASE
> +       l.nop   2
> +       l.j     return
> +       l.nop
> +test2:
> +       l.sfnei r7,0xf10 // test 2 - in delay slot, so PC should be of
> +       // preceeding l.j insn
> +       l.bf    fail
> +       l.nop
> +       // set the PC to step over the branch and range exception
> +       l.addi  r3,r3,8
> +       l.mtspr r0,r3,SPR_EPCR_BASE
> +       l.j     return
> +       l.nop
> +
> +return:
> +       // Clear the OV flag
> +       l.mfspr r3,r0,SPR_ESR_BASE
> +       l.xori  r3,r3,SPR_SR_OV
> +       l.mtspr r0,r3,SPR_ESR_BASE
> +       l.rfe
> +
> +
> +       .org 0xf00
> +ov_tests:
> +       // Cause some range exceptions at known PC
> +       // Trigger a range execption
> +       l.movhi r2,0x4000
> +
> +       // Test 1
> +       l.ori   r5,r0,1
> +       // Should have 0x40000000 + 0x40000000, at PC 0xf08
> +       l.add   r4,r2,r2
> +
> +       // Test 2 - delay slot
> +       l.ori   r5,r0,2
> +       l.j     a_place
> +       // Should have 0x40000000 + 0x40000000, at PC 0xf10 (insn before as
> +       // we're in delay slot)
> +       l.add   r4,r2,r2
> +a_place:
> +       l.nop
> +       // Check if we've run with cache yet - if so then
> +       // r10 will contain nonzero
> +       l.sfeq  r10,r0
> +       l.bnf   pass
> +       l.nop
> +       // Init caches and restart
> +       l.jal   _cache_init
> +       l.nop
> +       l.j     _start
> +       l.ori   r10,r0,1
> +
> +pass:
> +       l.movhi r3,0
> +       l.nop 1
> +
> +
> +/* =================================================== [ text section ] === 
> */
> +       .section  .text
> +
> +/* =================================================== [ start ] === */
> +
> +       .global _start
> +_start:
> +       // Set up SR to have range exception enabled
> +       l.mfspr r3, r0, SPR_SR
> +       l.nop   0x2
> +       l.ori   r3,r3,SPR_SR_OVE
> +       l.nop   0x2
> +       l.mtspr r0,r3,SPR_SR
> +
> +       // Now jump to the tests
> +       l.movhi r1,hi(ov_tests)
> +       l.ori   r1,r1,lo(ov_tests)
> +       l.jr    r1
> +       l.nop
> +
> +fail:
> +       l.nop   2
> +       l.ori   r3,r0,1
> +       l.nop   1

I've committed this and updated the bug:

http://bugzilla.opencores.org/bugzilla4/show_bug.cgi?id=90

Julius
_______________________________________________
OpenRISC mailing list
[email protected]
http://lists.openrisc.net/listinfo/openrisc

Reply via email to