OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [orpsocv2/] [sw/] [tests/] [or1200/] [board/] [or1200-mul.c] - Blame information for rev 446

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 439 julius
/*
2
   Test integer multiply
3
 
4
   Use a software multiplication algorithm to compare against hardware
5
   calculated results
6
 
7
   Julius Baxter, julius@opencores.org
8
 
9
*/
10
 
11
#include "cpu-utils.h"
12
#include "uart.h"
13
#include "printf.h"
14
#include "board.h"
15
 
16
static int smul_errors, umul_errors;
17
 
18
#define VERBOSE_TESTS 0
19
 
20
// Make this bigger when running on FPGA target. For simulation it's enough.
21
#define NUM_TESTS 2000000
22
 
23
int
24
or1k_mul(int multiplicant, int multiplier)
25
{
26
  int result;
27
  asm ("l.mul\t%0,%1,%2" : "=r" (result) : "r" (multiplicant),
28
       "r" (multiplier));
29
  return result;
30
}
31
 
32
unsigned int
33
or1k_mulu(unsigned int mulidend, unsigned int mulisor)
34
{
35
  int result;
36
  asm ("l.mulu\t%0,%1,%2" : "=r" (result) : "r" (mulidend), "r" (mulisor));
37
  return result;
38
}
39
 
40
 
41
void
42
check_mul(int multiplicand, int multiplier, int expected_result)
43
{
44
#if VERBOSE_TESTS
45
  printf("l.mul 0x%.8x * 0x%.8x = (SW) 0x%.8x : ", multiplicand, multiplier,
46
         expected_result);
47
#endif
48
  int result =  or1k_mul(multiplicand, multiplier);
49
  report(result);
50
  if ( result != expected_result)
51
    {
52
      printf("l.mul  0x%.8x * 0x%.8x = (SW) 0x%.8x : ", multiplicand, multiplier,
53
             expected_result);
54
 
55
      printf("(HW) 0x%.8x - MISMATCH\n",result);
56
      smul_errors++;
57
    }
58
#if VERBOSE_TESTS
59
  else
60
    printf("OK\n");
61
#endif
62
 
63
}
64
 
65
void
66
check_mulu(unsigned int multiplicand, unsigned int multiplier,
67
           unsigned int expected_result)
68
{
69
#if VERBOSE_TESTS
70
  printf("l.mulu 0x%.8x * 0x%.8x = (SW) 0x%.8x : ", multiplicand, multiplier,
71
         expected_result);
72
#endif
73
 
74
  unsigned int result =  or1k_mulu(multiplicand, multiplier);
75
  report(result);
76
  if ( result != expected_result)
77
    {
78
      printf("l.mulu 0x%.8x * 0x%.8x = (SW) 0x%.8x : ", multiplicand, multiplier,
79
             expected_result);
80
 
81
      printf("(HW) 0x%.8x - MISMATCH\n",result);
82
      umul_errors++;
83
    }
84
#if VERBOSE_TESTS
85
  else
86
    printf("OK\n");
87
#endif
88
}
89
 
90
 
91
// Software implementation of multiply
92
unsigned int
93
mul_soft(unsigned int n, unsigned int d)
94
{
95
 
96
  unsigned int m = 0;
97
  //printf("sft: 0x%x 0x%xd\n",n,d);
98
  int i;
99
  for(i=0; i<32; i++)
100
    {
101
      //printf("bit %d: 0x%x\n",i, (((1<<i) & d)));
102
      if ((1<<i) & d)
103
        {
104
          m += (unsigned int) (n << i);
105
        }
106
    }
107
 
108
  return (unsigned int) m;
109
}
110
 
111
int
112
main(void)
113
{
114
#ifdef _UART_H_
115
  uart_init(DEFAULT_UART);
116
#endif
117
 
118
  unsigned int seconds = 0;
119
  cpu_reset_timer_ticks();
120
  cpu_enable_timer();
121
 
122
  printf("\n\n\tOR1200 Multiplication Instruction Tests\n");
123
  printf("\tRunning %d tests\n", NUM_TESTS);
124
  printf("\tElapsed time: 000");
125
 
126
  // Variables for tracking errors
127
  umul_errors = 0;
128
  smul_errors = 0;
129
 
130
  int i;
131
 
132
  unsigned int n, d;
133
  unsigned int expected_result;
134
  i=0;
135
  n=0;d=0;
136
  while(i < NUM_TESTS)
137
    {
138
 
139
      n = rand() >> 20;
140
      d = (rand() >> 24);
141
 
142
      report(0x10101010);
143
 
144
 
145
      if (n&0x10) // Randomly select if we should negate n
146
        {
147
          // 2's complement of n
148
          n = ~n + 1;
149
        }
150
 
151
      if (d&0x80) // Randomly select if we should negate d
152
        {
153
          // 2's complement of d
154
          d = ~d + 1;
155
        }
156
 
157
      if ((n & 0x80000000) && (d & 0x80000000))
158
        expected_result = mul_soft(~(n-1), ~(d-1));
159
      else if ((n & 0x80000000) && !(d & 0x80000000))
160
        {
161
          expected_result = mul_soft(~(n-1), d);
162
          expected_result = ~expected_result + 1; // 2's complement
163
        }
164
      else if (!(n & 0x80000000) && (d & 0x80000000))
165
        {
166
          expected_result = mul_soft(n, ~(d-1));
167
          expected_result = ~expected_result + 1; // 2's complement
168
        }
169
      else if (!(n & 0x80000000) && !(d & 0x80000000))
170
        expected_result = mul_soft(n, d);
171
 
172
 
173
      /* Report things */
174
      report(n);
175
      report(d);
176
      report(expected_result);
177
 
178
 
179
      /* Signed mulide */
180
      check_mul(n, d, expected_result);
181
 
182
 
183
      /* Unsigned mulide test */
184
      /* Ensure numerator's bit 31 is clear */
185
      n >>= 1;
186
 
187
      expected_result = mul_soft(n, d);
188
 
189
      /* Report things */
190
      report(n);
191
      report(d);
192
      report(expected_result);
193
 
194
      /* Unsigned mulide */
195
      check_mulu(n, d, expected_result);
196
 
197
      report(i);
198
      i++;
199
 
200
 
201
      if (cpu_get_timer_ticks() >= TICKS_PER_SEC)
202
        {
203
          cpu_reset_timer_ticks();
204
          seconds++;
205
          printf("\b\b\b%.3d",seconds);
206
        }
207
 
208
    }
209
 
210
  printf("\n");
211
 
212
  printf("Integer multiply check complete\n");
213
  printf("Unsigned:\t%d tests\t %d errors\n",
214
         NUM_TESTS, umul_errors);
215
  printf("Signed:\t\t%d tests\t %d errors\n",
216
         NUM_TESTS, smul_errors);
217
 
218
  if ((umul_errors > 0) || (smul_errors > 0))
219
    report(0xbaaaaaad);
220
  else
221
    report(0x8000000d);
222
 
223
  return 0;
224
 
225
}

powered by: WebSVN 2.1.0

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