OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [tags/] [or1ksim/] [or1ksim-0.3.0/] [testbench/] [tick.c] - Diff between revs 19 and 21

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 19 Rev 21
/* tick.c -- Tests all aspects of the tick timer
/* tick.c -- Tests all aspects of the tick timer
   Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
   Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
 
 
This file is part of OpenRISC 1000 Architectural Simulator.
This file is part of OpenRISC 1000 Architectural Simulator.
 
 
This program is free software; you can redistribute it and/or modify
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
(at your option) any later version.
 
 
This program is distributed in the hope that it will be useful,
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
GNU General Public License for more details.
 
 
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 
#include "spr_defs.h"
#include "spr_defs.h"
#include "support.h"
#include "support.h"
 
 
#define ASSERT(x) ((x)? printf(" Test succeeded %s:%i\n", __FILE__, __LINE__) : fail (__FILE__, __LINE__))
#define ASSERT(x) ((x)? printf(" Test succeeded %s:%i\n", __FILE__, __LINE__) : fail (__FILE__, __LINE__))
 
 
void fail (char *func, int line)
void fail (char *func, int line)
{
{
#ifndef __FUNCTION__
#ifndef __FUNCTION__
#define __FUNCTION__ "?"
#define __FUNCTION__ "?"
#endif
#endif
  printf ("Test failed in %s:%i\n", func, line);
  printf ("Test failed in %s:%i\n", func, line);
  report(0xeeeeeeee);
  report(0xeeeeeeee);
  exit (1);
  exit (1);
}
}
 
 
static volatile int tick_cnt = 0;
static volatile int tick_cnt = 0;
static int clear_ip = 1;
static int clear_ip = 1;
 
 
void tick_int(void)
void tick_int(void)
{
{
  int ttcr = mfspr(SPR_TTCR);
  int ttcr = mfspr(SPR_TTCR);
  int ttmr = mfspr(SPR_TTMR);
  int ttmr = mfspr(SPR_TTMR);
 
 
  /* Make sure that the tick timer interrupt pending bit is set */
  /* Make sure that the tick timer interrupt pending bit is set */
  ASSERT(mfspr(SPR_TTMR) & SPR_TTMR_IP);
  ASSERT(mfspr(SPR_TTMR) & SPR_TTMR_IP);
 
 
  tick_cnt++;
  tick_cnt++;
 
 
  /* Clear interrupt (Write a 0 to SPR_TTMR_IP) */
  /* Clear interrupt (Write a 0 to SPR_TTMR_IP) */
  /* If we programmed a one-shot timer, make sure to disable the interrupts,
  /* If we programmed a one-shot timer, make sure to disable the interrupts,
   * else we'd get a spurious interrupt */
   * else we'd get a spurious interrupt */
  if((ttmr & SPR_TTMR_M) != 0x80000000)
  if((ttmr & SPR_TTMR_M) != 0x80000000)
    mtspr(SPR_TTMR, mfspr(SPR_TTMR) & ~SPR_TTMR_IP);
    mtspr(SPR_TTMR, mfspr(SPR_TTMR) & ~SPR_TTMR_IP);
  else
  else
    mtspr(SPR_TTMR, mfspr(SPR_TTMR) & ~(SPR_TTMR_IP | SPR_TTMR_IE));
    mtspr(SPR_TTMR, mfspr(SPR_TTMR) & ~(SPR_TTMR_IP | SPR_TTMR_IE));
}
}
 
 
void tick_int_spurious(void)
void tick_int_spurious(void)
{
{
  /* Make sure that the tick timer interrupt pending bit is set */
  /* Make sure that the tick timer interrupt pending bit is set */
  ASSERT(mfspr(SPR_TTMR) & SPR_TTMR_IP);
  ASSERT(mfspr(SPR_TTMR) & SPR_TTMR_IP);
 
 
  /* Clear interrupt (Write a 0 to SPR_TTMR_IP) */
  /* Clear interrupt (Write a 0 to SPR_TTMR_IP) */
  if(clear_ip)
  if(clear_ip)
    mtspr(SPR_TTMR, mfspr(SPR_TTMR) & ~SPR_TTMR_IP);
    mtspr(SPR_TTMR, mfspr(SPR_TTMR) & ~SPR_TTMR_IP);
 
 
  /* Make sure we actually get a spurious interrupt */
  /* Make sure we actually get a spurious interrupt */
  if(++tick_cnt == 5)
  if(++tick_cnt == 5)
    /* We should get spurious tick interrupts so disable it */
    /* We should get spurious tick interrupts so disable it */
    mtspr(SPR_TTMR, 0);
    mtspr(SPR_TTMR, 0);
}
}
 
 
/* Does nothing for a small amount of time (waiting for TTCR to increment) */
/* Does nothing for a small amount of time (waiting for TTCR to increment) */
void waste_time(void)
void waste_time(void)
{
{
  int i;
  int i;
  volatile int x;
  volatile int x;
 
 
  for(i = 0; i < 50; i++)
  for(i = 0; i < 50; i++)
    x = i;
    x = i;
}
}
 
 
/* Waits for a tick timer exception */
/* Waits for a tick timer exception */
void wait_match(void)
void wait_match(void)
{
{
  while(!tick_cnt);
  while(!tick_cnt);
  tick_cnt = 0;
  tick_cnt = 0;
}
}
 
 
int main()
int main()
{
{
  int ttcr;
  int ttcr;
 
 
  excpt_tick = (unsigned long)tick_int;
  excpt_tick = (unsigned long)tick_int;
 
 
  /* Enable tick interrupt */
  /* Enable tick interrupt */
  mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_TEE);
  mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_TEE);
 
 
  /* Disable timer */
  /* Disable timer */
  mtspr(SPR_TTMR, 0);
  mtspr(SPR_TTMR, 0);
 
 
  mtspr(SPR_TTCR, 0);
  mtspr(SPR_TTCR, 0);
 
 
  /* Waste some time to check if the timer is really disabled */
  /* Waste some time to check if the timer is really disabled */
  waste_time();
  waste_time();
 
 
  /* Timer is disabled and shouldn't count, TTCR should still be 0 */
  /* Timer is disabled and shouldn't count, TTCR should still be 0 */
  ASSERT(mfspr(SPR_TTCR) == 0);
  ASSERT(mfspr(SPR_TTCR) == 0);
 
 
  /* Start timer in continous timeing mode.  Enable timer interrupt and set the
  /* Start timer in continous timeing mode.  Enable timer interrupt and set the
   * value to match */
   * value to match */
  mtspr(SPR_TTMR, (3 << 30) | SPR_TTMR_IE | 0x100);
  mtspr(SPR_TTMR, (3 << 30) | SPR_TTMR_IE | 0x100);
 
 
  /* Wait for the timer to count up to the match value */
  /* Wait for the timer to count up to the match value */
  wait_match();
  wait_match();
 
 
  ttcr = mfspr(SPR_TTCR);
  ttcr = mfspr(SPR_TTCR);
 
 
  waste_time();
  waste_time();
 
 
  /* The timer should have kept counting and our saved ttcr should not be the
  /* The timer should have kept counting and our saved ttcr should not be the
   * same as SPR_TTCR */
   * same as SPR_TTCR */
  ASSERT(ttcr < mfspr(SPR_TTCR));
  ASSERT(ttcr < mfspr(SPR_TTCR));
 
 
  mtspr(SPR_TTMR, 0);
  mtspr(SPR_TTMR, 0);
  ttcr = mfspr(SPR_TTCR);
  ttcr = mfspr(SPR_TTCR);
  /* Restart the timer */
  /* Restart the timer */
  mtspr(SPR_TTMR, (3 << 30));
  mtspr(SPR_TTMR, (3 << 30));
  waste_time();
  waste_time();
  /* The timer should have carried on from what was SPR_TTCR when we started it.
  /* The timer should have carried on from what was SPR_TTCR when we started it.
   */
   */
  ASSERT(ttcr < mfspr(SPR_TTCR));
  ASSERT(ttcr < mfspr(SPR_TTCR));
 
 
  mtspr(SPR_TTMR, 0);
  mtspr(SPR_TTMR, 0);
  ttcr = mfspr(SPR_TTCR);
  ttcr = mfspr(SPR_TTCR);
  waste_time();
  waste_time();
  /* Timer should be disabled and should not have counted */
  /* Timer should be disabled and should not have counted */
  ASSERT(ttcr == mfspr(SPR_TTCR));
  ASSERT(ttcr == mfspr(SPR_TTCR));
 
 
  /* Stop the timer when a match occured */
  /* Stop the timer when a match occured */
  mtspr(SPR_TTCR, 0);
  mtspr(SPR_TTCR, 0);
  mtspr(SPR_TTMR, (2 << 30) | SPR_TTMR_IE | 0x100);
  mtspr(SPR_TTMR, (2 << 30) | SPR_TTMR_IE | 0x100);
 
 
  wait_match();
  wait_match();
  ttcr = mfspr(SPR_TTCR);
  ttcr = mfspr(SPR_TTCR);
  waste_time();
  waste_time();
  /* The timer should have stoped and thus SPR_TTCR sould = ttcr */
  /* The timer should have stoped and thus SPR_TTCR sould = ttcr */
  ASSERT(ttcr == mfspr(SPR_TTCR));
  ASSERT(ttcr == mfspr(SPR_TTCR));
 
 
  /* The counter should still indicate one-shot mode */
  /* The counter should still indicate one-shot mode */
  ASSERT((mfspr(SPR_TTMR) >> 30) == 2);
  ASSERT((mfspr(SPR_TTMR) >> 30) == 2);
 
 
  /* Set auto-restarting timer */
  /* Set auto-restarting timer */
  mtspr(SPR_TTMR, 0);
  mtspr(SPR_TTMR, 0);
  mtspr(SPR_TTCR, 0);
  mtspr(SPR_TTCR, 0);
  mtspr(SPR_TTMR, (1 << 30) | SPR_TTMR_IE | 0x1000);
  mtspr(SPR_TTMR, (1 << 30) | SPR_TTMR_IE | 0x1000);
  wait_match();
  wait_match();
  ttcr = mfspr(SPR_TTCR);
  ttcr = mfspr(SPR_TTCR);
  wait_match();
  wait_match();
 
 
  /* Disable timer */
  /* Disable timer */
  mtspr(SPR_TTMR, 0);
  mtspr(SPR_TTMR, 0);
 
 
  /* Start a one-shot counter but keep interrupts disabled */
  /* Start a one-shot counter but keep interrupts disabled */
  mtspr(SPR_TTCR, 0);
  mtspr(SPR_TTCR, 0);
  mtspr(SPR_TTMR, (2 << 30) | 0x100);
  mtspr(SPR_TTMR, (2 << 30) | 0x100);
 
 
  /* Wait for the counter to stop */
  /* Wait for the counter to stop */
  while(mfspr(SPR_TTCR) != 0x100);
  while(mfspr(SPR_TTCR) != 0x100);
  /* Make sure the counter has actually stopped */
  /* Make sure the counter has actually stopped */
  waste_time();
  waste_time();
  ASSERT(mfspr(SPR_TTCR) == 0x100);
  ASSERT(mfspr(SPR_TTCR) == 0x100);
  ASSERT(tick_cnt == 0);
  ASSERT(tick_cnt == 0);
 
 
  /* SPR_TTMR_IP should not be set */
  /* SPR_TTMR_IP should not be set */
  ASSERT(!(mfspr(SPR_TTMR) & SPR_TTMR_IP));
  ASSERT(!(mfspr(SPR_TTMR) & SPR_TTMR_IP));
 
 
  /* Start a perpetual counter (makeing sure that no interrupts occur while it's
  /* Start a perpetual counter (makeing sure that no interrupts occur while it's
   * counting) */
   * counting) */
  mtspr(SPR_TTMR, 0);
  mtspr(SPR_TTMR, 0);
  mtspr(SPR_TTCR, 0);
  mtspr(SPR_TTCR, 0);
  mtspr(SPR_TTMR, (3 << 30) | 0x100);
  mtspr(SPR_TTMR, (3 << 30) | 0x100);
  while(mfspr(SPR_TTCR) < 0x100);
  while(mfspr(SPR_TTCR) < 0x100);
  waste_time();
  waste_time();
  ASSERT(mfspr(SPR_TTCR) > 0x100);
  ASSERT(mfspr(SPR_TTCR) > 0x100);
  ASSERT(tick_cnt == 0);
  ASSERT(tick_cnt == 0);
  ASSERT(!(mfspr(SPR_TTMR) & SPR_TTMR_IP));
  ASSERT(!(mfspr(SPR_TTMR) & SPR_TTMR_IP));
 
 
  /* Disable the timer interrupt */
  /* Disable the timer interrupt */
  mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_TEE);
  mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_TEE);
 
 
  /* Set one-shot timer */
  /* Set one-shot timer */
  mtspr(SPR_TTCR, 0);
  mtspr(SPR_TTCR, 0);
  mtspr(SPR_TTMR, (2 << 30) | SPR_TTMR_IE | 0x100);
  mtspr(SPR_TTMR, (2 << 30) | SPR_TTMR_IE | 0x100);
  while(!(mfspr(SPR_TTMR) & SPR_TTMR_IP));
  while(!(mfspr(SPR_TTMR) & SPR_TTMR_IP));
  /* Give some time for a potential interrupt to occur */
  /* Give some time for a potential interrupt to occur */
  waste_time();
  waste_time();
  /* No interrupt should have occured */
  /* No interrupt should have occured */
  ASSERT(tick_cnt == 0);
  ASSERT(tick_cnt == 0);
 
 
  /* Enable tick interrupt */
  /* Enable tick interrupt */
  mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_TEE);
  mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_TEE);
 
 
  /* Test Setting TTCR while counting */
  /* Test Setting TTCR while counting */
  mtspr(SPR_TTMR, 0);
  mtspr(SPR_TTMR, 0);
  mtspr(SPR_TTCR, 0);
  mtspr(SPR_TTCR, 0);
  mtspr(SPR_TTMR, (3 << 30) | 0x3000);
  mtspr(SPR_TTMR, (3 << 30) | 0x3000);
  while(mfspr(SPR_TTCR) < 0x30000);
  while(mfspr(SPR_TTCR) < 0x30000);
  waste_time();
  waste_time();
  mtspr(SPR_TTCR, 0x50);
  mtspr(SPR_TTCR, 0x50);
  waste_time();
  waste_time();
  ttcr = mfspr(SPR_TTCR);
  ttcr = mfspr(SPR_TTCR);
  ASSERT(ttcr > 0x50 && ttcr < 0x30000);
  ASSERT(ttcr > 0x50 && ttcr < 0x30000);
  mtspr(SPR_TTMR, 0);
  mtspr(SPR_TTMR, 0);
 
 
  /* Set ttcr to a high value */
  /* Set ttcr to a high value */
  mtspr(SPR_TTCR, 0x20000);
  mtspr(SPR_TTCR, 0x20000);
  /* Now, start timer in one-shot mode */
  /* Now, start timer in one-shot mode */
  mtspr(SPR_TTMR, (2 << 30) | SPR_TTMR_IE | 0x100);
  mtspr(SPR_TTMR, (2 << 30) | SPR_TTMR_IE | 0x100);
 
 
  /* The counter should start counting from 0x20000 and wrap around to 0x100
  /* The counter should start counting from 0x20000 and wrap around to 0x100
   * causeing an interrupt */
   * causeing an interrupt */
  waste_time();
  waste_time();
  ASSERT(mfspr(SPR_TTCR) > 0x20000);
  ASSERT(mfspr(SPR_TTCR) > 0x20000);
  wait_match();
  wait_match();
 
 
  ASSERT(1);
  ASSERT(1);
 
 
  /* If TTCR is greater than TTMR_PERIOD then the interrupt gets delivered after
  /* If TTCR is greater than TTMR_PERIOD then the interrupt gets delivered after
   * TTCR wraps around to 0 and counts to SPR_TTMR_PERIOD */
   * TTCR wraps around to 0 and counts to SPR_TTMR_PERIOD */
  mtspr(SPR_TTMR, 0);
  mtspr(SPR_TTMR, 0);
  mtspr(SPR_TTCR, 0xffffc00);
  mtspr(SPR_TTCR, 0xffffc00);
  mtspr(SPR_TTMR, (1 << 30) | SPR_TTMR_IE | 0x10000);
  mtspr(SPR_TTMR, (1 << 30) | SPR_TTMR_IE | 0x10000);
  wait_match();
  wait_match();
 
 
  ASSERT(1);
  ASSERT(1);
 
 
  /* test continuous mode */
  /* test continuous mode */
  mtspr(SPR_TTMR, 0);
  mtspr(SPR_TTMR, 0);
  mtspr(SPR_TTCR, 0xffffc00);
  mtspr(SPR_TTCR, 0xffffc00);
  mtspr(SPR_TTMR, (3 << 30) | SPR_TTMR_IE | 0x10000);
  mtspr(SPR_TTMR, (3 << 30) | SPR_TTMR_IE | 0x10000);
  wait_match();
  wait_match();
  mtspr(SPR_TTMR, 0);
  mtspr(SPR_TTMR, 0);
 
 
  ASSERT(1);
  ASSERT(1);
 
 
  excpt_tick = (unsigned long)tick_int_spurious;
  excpt_tick = (unsigned long)tick_int_spurious;
 
 
  /* Make sure sure that TTMR_PERIOD is not 0!! */
  /* Make sure sure that TTMR_PERIOD is not 0!! */
  mtspr(SPR_TTMR, 1);
  mtspr(SPR_TTMR, 1);
  /* Set SPR_TTMR_PERIOD to some value, while keeping the timer disabled */
  /* Set SPR_TTMR_PERIOD to some value, while keeping the timer disabled */
  mtspr(SPR_TTCR, 0);
  mtspr(SPR_TTCR, 0);
  mtspr(SPR_TTMR, SPR_TTMR_IE | 0x100);
  mtspr(SPR_TTMR, SPR_TTMR_IE | 0x100);
 
 
  /* Set SPR_TTCR with the same value */
  /* Set SPR_TTCR with the same value */
  mtspr(SPR_TTCR, 0x100);
  mtspr(SPR_TTCR, 0x100);
 
 
  while(tick_cnt != 5);
  while(tick_cnt != 5);
  tick_cnt = 0;
  tick_cnt = 0;
  ASSERT(mfspr(SPR_TTCR) == 0x100);
  ASSERT(mfspr(SPR_TTCR) == 0x100);
 
 
  /* Test setting TTCR first then TTMR */
  /* Test setting TTCR first then TTMR */
  mtspr(SPR_TTCR, 0x101);
  mtspr(SPR_TTCR, 0x101);
  mtspr(SPR_TTMR, SPR_TTMR_IE | 0x101);
  mtspr(SPR_TTMR, SPR_TTMR_IE | 0x101);
 
 
  while(tick_cnt != 5);
  while(tick_cnt != 5);
  tick_cnt = 0;
  tick_cnt = 0;
  ASSERT(mfspr(SPR_TTCR) == 0x101);
  ASSERT(mfspr(SPR_TTCR) == 0x101);
 
 
  /* Set countinous counter, but make sure we never clear the TTMR_IP bit */
  /* Set countinous counter, but make sure we never clear the TTMR_IP bit */
  clear_ip = 0;
  clear_ip = 0;
  mtspr(SPR_TTCR, 0);
  mtspr(SPR_TTCR, 0);
  mtspr(SPR_TTMR, (3 << 30) | SPR_TTMR_IE | 0x100);
  mtspr(SPR_TTMR, (3 << 30) | SPR_TTMR_IE | 0x100);
 
 
  while(tick_cnt != 5);
  while(tick_cnt != 5);
 
 
  report(0xdeaddead);
  report(0xdeaddead);
  return 0;
  return 0;
}
}
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.