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 _______________________________________________ OpenRISC mailing list [email protected] http://lists.openrisc.net/listinfo/openrisc
