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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1200/] [rtl/] [verilog/] [or1200_fpu.v] - Blame information for rev 185

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

Line No. Rev Author Line
1 185 julius
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  OR1200's FPU Wrapper                                        ////
4
////                                                              ////
5
////  This file is part of the OpenRISC 1200 project              ////
6
////  http://opencores.org/project,or1k                           ////
7
////                                                              ////
8
////  Description                                                 ////
9
////  Wrapper for floating point unit.                            ////
10
////  Interface based on MULT/MAC unit.                           ////
11
////                                                              ////
12
////  To Do:                                                      ////
13
////   - remainder instruction implementation                     ////
14
////   - registering in/around compare unit                       ////
15
////                                                              ////
16
////  Author(s):                                                  ////
17
////      - Julius Baxter, julius@opencores.org                   ////
18
////                                                              ////
19
//////////////////////////////////////////////////////////////////////
20
////                                                              ////
21
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
22
////                                                              ////
23
//// This source file may be used and distributed without         ////
24
//// restriction provided that this copyright statement is not    ////
25
//// removed from the file and that any derivative work contains  ////
26
//// the original copyright notice and the associated disclaimer. ////
27
////                                                              ////
28
//// This source file is free software; you can redistribute it   ////
29
//// and/or modify it under the terms of the GNU Lesser General   ////
30
//// Public License as published by the Free Software Foundation; ////
31
//// either version 2.1 of the License, or (at your option) any   ////
32
//// later version.                                               ////
33
////                                                              ////
34
//// This source is distributed in the hope that it will be       ////
35
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
36
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
37
//// PURPOSE.  See the GNU Lesser General Public License for more ////
38
//// details.                                                     ////
39
////                                                              ////
40
//// You should have received a copy of the GNU Lesser General    ////
41
//// Public License along with this source; if not, download it   ////
42
//// from http://www.opencores.org/lgpl.shtml                     ////
43
////                                                              ////
44
//////////////////////////////////////////////////////////////////////
45
 
46
// synopsys translate_off
47
`include "timescale.v"
48
// synopsys translate_on
49
`include "or1200_defines.v"
50
 
51
module or1200_fpu(
52
                  // Clock and reset
53
                  clk, rst,
54
 
55
                  // FPU interface
56
                  ex_freeze, a, b, fpu_op, result,
57
 
58
                  // Flag controls
59
                  flagforw, flag_we,
60
 
61
                  // Exception signal
62
                  sig_fp, except_started,
63
 
64
                  // SPR interface
65
                  fpcsr_we, fpcsr,
66
                  spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o
67
                  );
68
 
69
   parameter width = `OR1200_OPERAND_WIDTH;
70
 
71
   //
72
   // I/O
73
   //
74
 
75
   //
76
   // Clock and reset
77
   //
78
   input                                clk;
79
   input                                rst;
80
 
81
   //
82
   // FPU interface
83
   //
84
   input                                ex_freeze;
85
   input [width-1:0]                     a;
86
   input [width-1:0]                     b;
87
   input [`OR1200_FPUOP_WIDTH-1:0]       fpu_op;
88
   output [width-1:0]                    result;
89
 
90
   //
91
   // Flag signals
92
   //
93
   output                               flagforw;
94
   output                               flag_we;
95
 
96
 
97
   //
98
   // FPCSR interface
99
   //  
100
   input                                fpcsr_we;
101
   output [`OR1200_FPCSR_WIDTH-1:0]      fpcsr;
102
 
103
   //
104
   // Exception signal
105
   //   
106
   output                               sig_fp;
107
   input                                except_started;
108
 
109
 
110
   //
111
   // SPR interface
112
   //
113
   input                                spr_cs;
114
   input                                spr_write;
115
   input [31:0]                  spr_addr;
116
   input [31:0]                  spr_dat_i;
117
   output [31:0]                         spr_dat_o;
118
 
119
   //
120
   // Internals
121
   //
122
   reg [2:0]                             fpu_op_count;
123
   reg [`OR1200_FPUOP_WIDTH:0]           fpu_op_r;
124
   reg [`OR1200_FPCSR_WIDTH-1:0]         fpcsr_r;
125
   reg                                  fpu_latch_operand;
126
   wire                                 fpu_check_op;
127
   wire                                 fpu_latch_op;
128
   wire                                 inf, snan, qnan, ine, overflow,
129
                                        underflow, zero, div_by_zero;
130
   wire                                 fpu_op_is_comp, fpu_op_r_is_comp;
131
   wire                                 altb, blta, aeqb, cmp_inf, cmp_zero,
132
                                        unordered ;
133
   reg                                  flag;
134
 
135
   assign fpcsr = fpcsr_r;
136
 
137
   assign sig_fp = fpcsr_r[`OR1200_FPCSR_FPEE]
138
            & (|fpcsr_r[`OR1200_FPCSR_WIDTH-1:`OR1200_FPCSR_OVF]);
139
 
140
   // Generate signals to latch fpu_op from decode instruction, then latch 
141
   // operands when they appear during execute stage
142
 
143
   assign fpu_check_op = (!ex_freeze & fpu_op[`OR1200_FPUOP_WIDTH-1]);
144
 
145
   assign fpu_op_is_comp = fpu_op[3];
146
 
147
   assign fpu_op_r_is_comp = fpu_op_r[3];
148
 
149
   assign fpu_latch_op = fpu_check_op & !fpu_op_is_comp;
150
 
151
   always @(posedge clk)
152
     fpu_latch_operand <= fpu_check_op & !fpu_op_is_comp;
153
 
154
   // Register fpu_op on comparisons, clear otherwise, remove top bit
155
   always @(posedge clk)
156
     fpu_op_r <= (fpu_check_op & fpu_op_is_comp) ?
157
                 {1'b0,fpu_op[`OR1200_FPUOP_WIDTH-2:0]} : !ex_freeze ?
158
 
159
 
160
   //
161
   // Counter for each FPU operation
162
   // Loaded at start, counts down
163
   //
164
   always @(posedge clk or posedge rst) begin
165
      if (rst)
166
        fpu_op_count <= 0;
167
      else
168
        if (|fpu_op_count)
169
          fpu_op_count <= fpu_op_count - 1;
170
        else if(fpu_check_op)
171
          fpu_op_count <= 5;
172
   end
173
 
174
   //
175
   // FPCSR register
176
   //   
177
   always @(posedge clk or posedge rst) begin
178
      if (rst)
179
        fpcsr_r <= 0;
180
      else
181
        begin
182
           if (fpcsr_we)
183
             fpcsr_r <= b[`OR1200_FPCSR_WIDTH-1:0];
184
           else if (fpu_op_count == 1)
185
             begin
186
                fpcsr_r[`OR1200_FPCSR_OVF] <= overflow;
187
                fpcsr_r[`OR1200_FPCSR_UNF] <= underflow;
188
                fpcsr_r[`OR1200_FPCSR_SNF] <= snan;
189
                fpcsr_r[`OR1200_FPCSR_QNF] <= qnan;
190
                fpcsr_r[`OR1200_FPCSR_ZF]  <= zero |
191
                                              (cmp_zero & fpu_op_r_is_comp);
192
                fpcsr_r[`OR1200_FPCSR_IXF] <= ine;
193
                fpcsr_r[`OR1200_FPCSR_IVF] <= 0; // Not used by this FPU
194
                fpcsr_r[`OR1200_FPCSR_INF] <= inf |
195
                                              (cmp_inf & fpu_op_r_is_comp);
196
                fpcsr_r[`OR1200_FPCSR_DZF] <= div_by_zero;
197
             end // if (fpu_op_count == 1)
198
           if (except_started)
199
             fpcsr_r[`OR1200_FPCSR_FPEE] <= 0;
200
        end // else: !if(rst)
201
   end // always @ (posedge clk or posedge rst)
202
 
203
   //
204
   // Comparison flag generation
205
   //
206
   always@(posedge clk)
207
     begin
208
        if (fpu_op_r_is_comp)
209
          begin
210
             case(fpu_op_r)
211
               `OR1200_FPCOP_SFEQ: begin
212
                  flag <= aeqb;
213
               end
214
               `OR1200_FPCOP_SFNE: begin
215
                  flag <= !aeqb;
216
               end
217
               `OR1200_FPCOP_SFGT: begin
218
                  flag <= blta & !aeqb;
219
               end
220
               `OR1200_FPCOP_SFGE: begin
221
                  flag <= blta | aeqb;
222
               end
223
               `OR1200_FPCOP_SFLT: begin
224
                  flag <= altb & !aeqb;
225
               end
226
               `OR1200_FPCOP_SFLE: begin
227
                  flag <= altb | aeqb;
228
               end
229
               default: begin
230
                  flag <= 0;
231
               end
232
             endcase // case (fpu_op_r)
233
          end // if (fpu_op_r_is_comp)
234
        else
235
          flag <= 0;
236
     end // always@ (posedge clk)
237
 
238
   assign flagforw = flag;
239
 
240
   // Determine here where we do the write, ie how much we pipeline the 
241
   // comparison   
242
   assign flag_we = fpu_op_r_is_comp & (fpu_op_count == 2);
243
 
244
   // FP arithmetic module
245
   fpu fpu0
246
     (
247
       .clk(clk),
248
       .rmode(fpcsr_r[`OR1200_FPCSR_RM]),
249
       .fpu_op(fpu_op[2:0]),
250
       .opa(a),
251
       .opb(b),
252
       .out(result),
253
       .latch_operand(fpu_latch_operand),
254
       .latch_op(fpu_latch_op),
255
       .inf(inf),
256
       .snan(snan),
257
       .qnan(qnan),
258
       .ine(ine),
259
       .overflow(overflow),
260
       .underflow(underflow),
261
       .zero(zero),
262
       .div_by_zero(div_by_zero)
263
       );
264
 
265
   // FP comparator
266
   fcmp fcmp0
267
     (
268
      .opa(a),
269
      .opb(b),
270
      .unordered(unordered),
271
      // I am convinced the comparison logic is wrong way around in this 
272
      // module, simplest to swap them on output -- julius
273
 
274
      .altb(blta),
275
      .blta(altb),
276
      .aeqb(aeqb),
277
      .inf(cmp_inf),
278
      .zero(cmp_zero));
279
 
280
 
281
endmodule // or1200_fpu

powered by: WebSVN 2.1.0

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