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

Subversion Repositories yacc

[/] [yacc/] [trunk/] [bench/] [c_src/] [calculator/] [uart_echo_test.c] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 tak.sugawa
//Apr.4.2005 Rewritten for RAM16K and Engilish
2
//RTL Simulation use Only 
3
//By using uart echo technique, UART interrupt routine and h/w are checked.
4
//YACC Project on CYCLONE 4KRAM
5
//Jul.15.2004 Simple 32bit calculator
6
// 
7
 
8
 
9
#define print_port 0x3ff0
10
#define print_char_port 0x3ff1
11
#define print_int_port 0x3ff2
12
#define print_long_port 0x3ff4
13
 
14
 
15
#define uart_port               0x03ffc //for 16KRAM
16
#define uart_wport uart_port
17
#define uart_rport uart_port
18
#define int_set_address 0x03ff8 //for 16KRAM
19
 
20
 
21
 
22
#define BUFFER_SIZE 120
23
unsigned char * read_ptr;
24
char buffer[BUFFER_SIZE];//
25
char result_buffer[8];//8+1
26
unsigned char sym;
27
unsigned char* char_ptr;
28
long term(void);
29
long factor(void);
30
long expression(void);
31
void calculator();
32
int volatile int_flag=0;//volatile is must. Without it,No calculation will be done because of Compiler Optimization.
33
char buf[2];
34
#define DEBUG //For RTL Simulation USE
35
void print_uart(unsigned char* ptr)// 
36
{
37
        #define WRITE_BUSY 0x0100
38
        unsigned uport;
39
        while (*ptr) {
40
                do {
41
                  uport=*(volatile unsigned*)   uart_port;
42
                } while (uport & WRITE_BUSY);
43
                *(volatile unsigned char*)uart_wport=*(ptr++);
44
        }
45
}
46
 
47
 
48
void putc_uart(unsigned char c)// 
49
{
50
        unsigned uport;
51
 
52
        do {
53
                  uport=*(volatile unsigned*)   uart_port;
54
        } while (uport & WRITE_BUSY);
55
 
56
        *(volatile unsigned char*)uart_wport=c;
57
}
58
 
59
void print_char(unsigned char val)// 
60
{
61
        #ifdef DOS
62
                printf("%x ",val);
63
        #else
64
        *(volatile unsigned char*)print_char_port=(unsigned char)val ;
65
        #endif
66
 
67
}
68
unsigned char read_uart()//Apr.4.2005 changed 32 bits port
69
{
70
        unsigned uport=*(volatile unsigned*)uart_port;
71
//      print_char(uport);
72
                return uport;
73
}
74
 
75
void print(unsigned char* ptr)//Verilog Test Bench Use 
76
{
77
        #ifdef DOS
78
                        printf("%s ",ptr);
79
        #else
80
 
81
        while (*ptr) {
82
 
83
                *(volatile unsigned char*)print_port=*(ptr++);
84
        }
85
 
86
        *(volatile unsigned char*)print_port=0x00;//Write Done
87
        #endif
88
}
89
 
90
void print_short(short val)//Little Endian write out 16bit number 
91
{
92
        #ifdef DOS
93
                printf("%x",val);
94
        #else
95
                *(volatile unsigned short*)print_int_port=val ;
96
        #endif
97
 
98
 
99
}
100
 
101
void print_long(unsigned long val)//Little Endian write out 32bit number 
102
{
103
        #ifdef DOS
104
                        printf("%x",val);
105
        #else
106
                        *(volatile unsigned long*)print_long_port=val;
107
 
108
        #endif
109
 
110
}
111
 
112
 
113
//Interrupt Service Routine.
114
//If 0D/0A comes then, 
115
//{write 0 at the end of buffer.
116
// Parse Analysis by hand,
117
//}else increment READ_PTR
118
//if Overflow MessageOUT
119
 void interrupt(void)
120
{
121
        char c;
122
#define SAVE_REGISTERS   (13*4)
123
        asm("addiu      $sp,$sp,-52 ;");//SAVE_REGISTERS
124
 
125
        asm("   sw      $a0,($sp)");//Save registers@
126
        asm("   sw  $v0,4($sp)");
127
        asm("   sw  $v1,8($sp)");
128
        asm("   sw  $a1,12($sp)");
129
        asm("   sw  $s0,16($sp)");
130
        asm("   sw  $s1,20($sp)");
131
        asm("   sw  $s2,24($sp)");
132
 
133
        asm("   sw  $a3,28($sp)");
134
        asm("   sw  $s4,32($sp)");
135
        asm("   sw  $s5,36($sp)");
136
        asm("   sw  $s6,40($sp)");
137
        asm("   sw  $s7,44($sp)");
138
        asm("   sw  $a2,48($sp)");
139
 
140
 
141
 
142
        c=read_uart();//read 1Byte from uart read port.
143
 
144
 
145
        if ( c == 0x0a || c==0x0d )
146
        {
147
                        *read_ptr = 0;//string end
148
                        read_ptr=buffer;//Initialization of read_ptr
149
 
150
 
151
                                putc_uart(0x0a);
152
                                putc_uart(0x0d);
153
 
154
                        if (int_flag) print("PError!\n");
155
                        else            int_flag=1;
156
 
157
        }  else if ( c == '\b' && read_ptr > buffer ){//Backspace
158
 
159
                                putc_uart('\b');
160
 
161
 
162
                        read_ptr--;
163
        }else if ( read_ptr>= buffer+BUFFER_SIZE){// overflow
164
                //
165
                        *read_ptr = 0;//string end
166
                        read_ptr=buffer;//Initialization of read_ptr
167
                        print_uart("Sorry Overflow..!\n");
168
 
169
        }else {//post increment
170
 
171
                                putc_uart(c);
172
 
173
                        *(read_ptr++) = c;
174
        }
175
 
176
#ifdef DEBUG
177
//      print(buffer);
178
//      print("\n\n");
179
#endif  
180
 
181
//Restore Saved Registers.
182
 
183
        asm("   lw      $a0,($sp)");
184
        asm("   lw  $v0,4($sp)");
185
        asm("   lw  $v1,8($sp)");
186
        asm("   lw  $a1,12($sp)");
187
        asm("   lw  $s0,16($sp)");
188
        asm("   lw  $s1,20($sp)");
189
        asm("   lw  $s2,24($sp)");
190
 
191
        asm("   lw  $a3,28($sp)");
192
        asm("   lw  $s4,32($sp)");
193
        asm("   lw  $s5,36($sp)");
194
        asm("   lw  $s6,40($sp)");
195
        asm("   lw  $s7,44($sp)");
196
        asm("   lw  $a2,48($sp)");
197
 
198
        asm("addiu      $sp,$sp,52 ;");//SAVE_REGISTERS
199
                                                        //Adjust! 
200
        asm("lw $ra,20($sp);");//Adjust! See dis-assemble list
201
        asm("addiu      $sp,$sp,24 ;");//Adjust.
202
    asm("jr     $26");//Return Interrupt
203
        asm("nop");//Delayed Slot
204
//
205
 
206
}
207
 
208
inline void set_interrupt_address()
209
{
210
        *(volatile unsigned long*)int_set_address=(unsigned long)interrupt;
211
        read_ptr=buffer;
212
}
213
 
214
 
215
void print_longlong(long long val)//Little Endian write out 32bit number 
216
{
217
        #ifdef DOS
218
                        printf("%x",val);
219
        #else
220
                        *(volatile unsigned long*)print_long_port=val>>32;
221
                        *(volatile unsigned long*)print_long_port=val;
222
 
223
        #endif
224
 
225
}
226
 
227
 
228
 void getsym()
229
{
230
 
231
 
232
        while ( *char_ptr==' ' ||
233
                        *char_ptr=='\n' ||
234
                        *char_ptr=='\r' ) char_ptr++;
235
        if (*char_ptr ==0) {
236
                sym=0;
237
        }else {
238
                sym=*(char_ptr++);
239
 
240
        }
241
}
242
 
243
inline void init_parser()
244
{
245
        char_ptr=buffer;
246
        getsym();
247
 
248
}
249
 
250
 
251
long evaluate_number(void)
252
{
253
 
254
        long x ;
255
 
256
        x=sym-'0';
257
        while(*char_ptr >='0' && *char_ptr <='9') {
258
                x = x * 10 + *char_ptr - '0';
259
                char_ptr++;
260
        }
261
        getsym();
262
 
263
        return x;
264
}
265
long expression(void)
266
{
267
        long term1,term2;
268
        unsigned char op;
269
 
270
        op=sym;
271
 
272
        if (sym=='+' || sym=='-') getsym();
273
        term1=term();
274
 
275
        if (op=='-') term1=-term1;
276
 
277
        while (sym=='+' || sym=='-') {
278
                op=sym;
279
                getsym();
280
                term2=term();
281
                if (op=='+') term1= term1+term2;
282
                else              term1= term1-term2;
283
        }
284
 
285
        return term1;
286
}
287
 
288
long term(void)
289
{
290
        unsigned char op;
291
        long factor1,factor2;
292
 
293
        factor1=factor();
294
        while ( sym=='*' || sym=='/' || sym=='%'){
295
                op=sym;
296
                getsym();
297
                factor2=factor();
298
 
299
                switch (op) {
300
                        case '*': factor1= factor1*factor2;
301
                                          break;
302
                        case '/': factor1= factor1/factor2;
303
                                          break;
304
                        case '%':   factor1= factor1%factor2;
305
                                          break;
306
                }
307
        }
308
 
309
        return factor1;
310
}
311
 
312
inline long parse_error()
313
{
314
        print_uart("\n parse error occurred\n");
315
        return 0;
316
}
317
 
318
long factor(void)
319
{
320
        int i;
321
 
322
        if (sym>='0' && sym <='9')       return evaluate_number();
323
        else if (sym=='('){
324
 
325
                                        getsym();
326
                                        i= expression();
327
 
328
                                        if (sym !=')'){
329
                                                parse_error();
330
                                        }
331
                                        getsym();
332
                                        return i;
333
        }else  if (sym==0) return 0;
334
        else return parse_error();
335
}
336
 
337
 
338
 
339
 
340
 
341
char *strrev(char *s) {
342
        char *ret = s;
343
        char *t = s;
344
        char c;
345
 
346
        while( *t != '\0' )t++;
347
        t--;
348
 
349
        while(t > s) {
350
                c = *s;
351
                *s = *t;
352
                *t = c;
353
                s++;
354
                t--;
355
        }
356
 
357
        return ret;
358
}
359
 
360
 
361
void itoa(int val, char *s) {
362
        char *t;
363
        int mod;
364
 
365
        if(val < 0) {
366
                *s++ = '-';
367
                val = -val;
368
        }
369
        t = s;
370
 
371
        while(val) {
372
                mod = val % 10;
373
                *t++ = (char)mod + '0';
374
                val /= 10;
375
 
376
        }
377
 
378
        if(s == t)
379
                *t++ = '0';
380
 
381
        *t = '\0';
382
 
383
 
384
        strrev(s);
385
}
386
void calculator()
387
{
388
        long result;
389
 
390
//Parser Initialization 
391
        init_parser();
392
 
393
//Calculation
394
        result=expression();
395
 
396
//      
397
        #ifdef DEBUG
398
        print("\n");
399
        print(buffer);
400
        print("=");
401
        print_long(result);
402
        print("[Hex]   ");
403
        itoa(result,result_buffer);
404
        print(result_buffer);
405
        print("[Dec]\n");
406
 
407
        #else
408
        print_uart(buffer);
409
        putc_uart('=');
410
        print_uart(result_buffer);
411
        putc_uart(0x0a);
412
        putc_uart(0x0a);
413
        putc_uart(0x0d);
414
 
415
        #endif  
416
 
417
 
418
}
419
 
420
void strcpy(char* dest,char* source)
421
{
422
 
423
        char* dest_ptr;
424
        dest_ptr=dest;
425
 
426
        while(*source) {
427
 
428
                *(dest++) =*(source++);
429
        } ;
430
 
431
        *dest=0;//Write Done
432
 
433
 
434
}
435
void calculator_test(char* ptr)
436
{
437
        strcpy(buffer,ptr);
438
        calculator();
439
 
440
}
441
 
442
void main()
443
{
444
        unsigned counter=0;
445
 
446
 
447
        set_interrupt_address();//Set Interrupt Service Address
448
 
449
    print_uart("5*3\n");//Send UART PORT TXD, then echo backed to RXD in verilog test bench.
450
        print_uart("100*31\n");//Don't care overflow,Altera Imprementation has UART FIFO 512bytes
451
        print_uart("(-31050)/(-31)\n");
452
        print_uart("(-1053333)/(231)\n");
453
    print_uart("(10503)/(-314)\n");
454
    print_uart("3333*3333\n");
455
        print_uart("533*443\n");
456
        print_uart("10*314\n");
457
        print_uart("(-350)/(-231)\n");
458
        print_uart("(-10533333)/(1231)\n");
459
    print_uart("(105034)/(-3134)\n");
460
    print_uart("3363*33333\n");
461
        label:
462
        if (int_flag){//if interrupt service routine reports end of string,
463
                        int_flag=0;
464
                        calculator();//then parse the string,calculates, and report the result to debug port.
465
                        counter++;
466
                        if (counter>=12)        print("$finish");
467
        }
468
        goto label;
469
 
470
}

powered by: WebSVN 2.1.0

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