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

Subversion Repositories systemc_cordic

[/] [systemc_cordic/] [trunk/] [cordic_ip/] [decoder.cpp] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 wwcheng
// decoder.cpp: source file
2
/********************************************************************
3
//
4
// Module:
5
//   Instruction Decoding Unit
6
//
7
// Implementation:
8
//   This module decodes the instruction and sets up the 12-stage
9
//   CORDIC pipeline
10
//
11
//
12
// Authors:     Winnie Cheng <wwcheng@stanford.edu>,
13
//              Peter Wu <peter5@stanford.edu>
14
//
15
 *********************************************************************/
16
 
17
#include "decoder.h"
18
#include "opcode.h"
19
#include "convert.h"
20
 
21
#ifdef MODULE_NAME
22
#undef MODULE_NAME
23
#endif
24
 
25
#define MODULE_NAME     "decoder"
26
 
27
#define DEBUG           1
28
#if DEBUG
29
#define dprintf         printf
30
#else
31
#define dprintf
32
#endif
33
 
34
#define NUM_STAGES      12
35
#define IDLE_SLACK      2*NUM_STAGES
36
 
37
void decoder::decoder_process()
38
{
39
    short flush;
40
    sc_uint<UNIT_SEL_WIDTH> ir;
41
    short op1, op2, op3;
42
 
43
    short x, y, acc_phase, desired_phase;
44
    short tmp_x;
45
 
46
    // On reset, initialize output
47
    enable_pipeline.write(false);
48
    out_x.write(0);
49
    out_y.write(0);
50
    out_acc_phase.write(0);
51
    out_opcode.write(I_NOP);
52
    out_desired_phase.write(0);
53
    flush = NUM_STAGES + IDLE_SLACK;
54
 
55
    while(1) {
56
        wait();
57
        if(start.read()==true) {
58
            flush = NUM_STAGES + IDLE_SLACK;    // reset counter
59
 
60
            // Registered input
61
            if(instruction_valid.read()==true) {
62
                // Read registered input
63
                ir = opcode.read();
64
                op1 = operand1.read();
65
                op2 = operand2.read();
66
                op3 = operand3.read();
67
 
68
                // Decode the opcode and adjust input
69
                if(ir == I_ROTATE) {
70
 
71
                    // Rotate Instruction Format
72
                    //   operand1 : orgX
73
                    //   operand2 : orgY
74
                    //   operand3 : angle
75
                    // returns
76
                    //   result1 : rotated x-coordinate
77
                    //   result2 : rotated y-coordinate   
78
 
79
                    x = op1;
80
                    y = op2;
81
                    acc_phase = op3;
82
 
83
                    if(acc_phase < 0) {
84
                        // If vector lies in fourth-quadrant, position to first-quadrant
85
                        x = -op1;
86
                        y = -op2;
87
                        acc_phase += INT180;
88
                    }
89
                    if (acc_phase > INT90) {
90
                        // If vector lies in third-quadrant, position to first-quadrant
91
                         tmp_x = x;
92
                         x = -y;
93
                         y = tmp_x;
94
                         acc_phase -=INT90;
95
                    }
96
 
97
                    dprintf("[%s] ROTATE\n", MODULE_NAME);
98
 
99
                } else if (ir == I_MAGPHASE) {
100
 
101
                    // Magphase Instruction Format
102
                    //   operand1 : X
103
                    //   operand2 : Y
104
                    // returns
105
                    //   result1 : magnitude
106
                    //   result2 : phase
107
 
108
                   x = op1;
109
                   y = op2;
110
 
111
                   if(x < 0) {
112
                       // rotate by an initial +/- 90 degrees
113
                       tmp_x = x;
114
                       if( y > 0) {
115
                           x = y;
116
                           y = -tmp_x;
117
                           acc_phase = -INT90;  // subtract 90 deg
118
                       } else {
119
                           x = -y;
120
                           y = tmp_x;
121
                           acc_phase = INT90;   // add 90 deg
122
                       }
123
                   } else {
124
                       acc_phase = 0;
125
                   }
126
                    dprintf("[%s] MAG-PHASE\n", MODULE_NAME);
127
                } else if (ir == I_SINCOS) {
128
 
129
                    // SinCos Instruction Format
130
                    //   operand1 : phase
131
                    // return
132
                    //   result1 : sin(phase)
133
                    //   result2 : cos(phase)
134
 
135
                    desired_phase = op1;
136
 
137
                    // start with +90, -90, or 0 degrees
138
                    if(desired_phase > INT90) {
139
                        x = 0;
140
                        y = START_SINCOS_Y;     // adjust with mult factor
141
                        acc_phase = INT90;
142
                    } else if (desired_phase < -INT90) {
143
                        x = 0;
144
                        y = -START_SINCOS_Y;
145
                        acc_phase = -INT90;
146
                    } else {
147
                        x = START_SINCOS_Y;
148
                        y = 0;
149
                        acc_phase = 0;
150
                    }
151
                    dprintf("[%s] SIN-COS\n", MODULE_NAME);
152
                } else if (ir == I_SINHCOSH) {
153
 
154
                    // SinhCosh Instruction Format
155
                    //   operand1 : phase
156
                    // return
157
                    //   result1 : sinh(phase)
158
                    //   result2 : cosh(phase)   
159
 
160
                    desired_phase = op1;
161
                    x = START_SINHCOSH_X;
162
                    y = 0;
163
                    acc_phase = 0;
164
                    dprintf("[%s] SINH-COSH\n", MODULE_NAME);
165
                }
166
 
167
                // write output
168
                enable_pipeline.write(true);
169
                out_x.write(x);
170
                out_y.write(y);
171
                out_acc_phase.write(acc_phase);
172
                out_opcode.write(ir);
173
                out_desired_phase.write(desired_phase);
174
 
175
            } else {
176
                // feed with NOP
177
                enable_pipeline.write(true);
178
                out_x.write(0);
179
                out_y.write(0);
180
                out_acc_phase.write(0);
181
                out_opcode.write(I_NOP);
182
                out_desired_phase.write(0);
183
            }
184
        } else {
185
            if(flush > 0) {
186
                // keep pipeline enable, flush with NOP
187
                enable_pipeline.write(true);
188
                flush--;
189
            } else {
190
                enable_pipeline.write(false);
191
                printf("[%s] Pipeline shutdown for power-save mode\n", MODULE_NAME);
192
            }
193
            out_x.write(0);
194
            out_y.write(0);
195
            out_acc_phase.write(0);
196
            out_opcode.write(I_NOP);
197
            out_desired_phase.write(0);
198
        }
199
 
200
    } // forever-loop   
201
}

powered by: WebSVN 2.1.0

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