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

Subversion Repositories openrisc_2011-10-31

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

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

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

powered by: WebSVN 2.1.0

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