source: XOpenSparcT1/trunk/T1-CPU/mul/sparc_mul_dp.v @ 6

Revision 6, 6.6 KB checked in by pntsvt00, 14 years ago (diff)

versione iniziale opensparc

Line 
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T1 Processor File: sparc_mul_dp.v
4// Copyright (c) 2006 Sun Microsystems, Inc.  All Rights Reserved.
5// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
6//
7// The above named program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public
9// License version 2 as published by the Free Software Foundation.
10//
11// The above named program is distributed in the hope that it will be
12// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14// General Public License for more details.
15//
16// You should have received a copy of the GNU General Public
17// License along with this work; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19//
20// ========== Copyright Header End ============================================
21//FPGA_SYN enables all FPGA related modifications
22`ifdef FPGA_SYN 
23`define FPGA_SYN_CLK_EN
24`define FPGA_SYN_CLK_DFF
25`endif
26
27module sparc_mul_dp(
28  ecl_mul_rs1_data,
29  ecl_mul_rs2_data,
30  spu_mul_op1_data,
31  spu_mul_op2_data,
32  valid,
33  spick,
34  byp_sel,
35  byp_imm,
36  acc_imm,
37  acc_actc2,
38  acc_actc3,
39  acc_actc5,
40  acc_reg_enb,
41  acc_reg_rst,
42  acc_reg_shf,
43  x2,
44  mul_data_out,
45  rst_l,
46  si,
47  so,
48  se,
49  rclk
50  );
51
52input [63:0]    ecl_mul_rs1_data;       // EXU mul operand 1
53input [63:0]    ecl_mul_rs2_data;       // EXU mul operand 2
54input [63:0]    spu_mul_op1_data;       // SPU mul operand 1   
55input [63:0]    spu_mul_op2_data;       // SPU mul operand 2   
56input           valid;                  // begin cyc0 of MUL operation
57input           spick;                  // Internal pick signals of exu, spu multiplier
58input           byp_sel;                // SPU bypass ACCUM[63:0] as operand
59input           byp_imm;                // SPU bypss action from mout immediately
60input           acc_imm;                // SPU accumlate from mout immediately
61input           acc_actc2, acc_actc3;   // accumulate enable for LSB-32 and All-96
62input           acc_actc5;              // accumulate enable for LSB-32 and All-96
63input           acc_reg_enb;            // ACCUM register enable
64input           acc_reg_rst;            // ACCUM register reset
65input           acc_reg_shf;            // ACCUM shift right 64-bit
66input           x2;                     // for op1*op2*2
67input           rst_l;                  // system  reset
68input           si;                     // si
69input           se;                     // scan_enable
70input           rclk;
71output          so;                     // so
72output [63:0]   mul_data_out;           // Multiplier outputs
73
74wire  [63:0]    mul_op1_d, mul_op2_d, bypreg;
75wire  [63:32]   mux1_reg, mux1_mou;
76wire  [96:0]    mux2_reg, areg;
77wire  [135:0]   mout, acc_reg_in, acc_reg;
78wire            op2_s0, op2_s1, op2_s2;
79wire            acc_reg_shf2, clk_enb1;
80wire            clk;
81
82assign clk = rclk ;
83
84///////////////////////////////////////////////////////////////////////////////
85//////  op1 inputs mux between EXU and SPU
86///////////////////////////////////////////////////////////////////////////////
87
88  assign mul_op1_d = ({64{spick}}  & spu_mul_op1_data) |
89                     ({64{~spick}} & ecl_mul_rs1_data );
90
91///////////////////////////////////////////////////////////////////////////////
92//////  op2 inputs mux between EXU, SPU and bypass from ACCUM register
93///////////////////////////////////////////////////////////////////////////////
94 
95  assign op2_s0 = ~spick;
96  assign op2_s1 = spick & byp_sel ; 
97  assign op2_s2 = spick & ~byp_sel ; 
98  assign mul_op2_d = (op2_s0 & op2_s1)|(op2_s0 & op2_s2)|(op2_s1 & op2_s2) ? 64'hxx :
99                     (op2_s0 ? ecl_mul_rs2_data : 
100                     (op2_s1 ? bypreg : 
101                     (op2_s2 ? spu_mul_op2_data : 64'hxx)
102                      ));
103 
104///////////////////////////////////////////////////////////////////////////////
105//////  Accumulate input muxes
106///////////////////////////////////////////////////////////////////////////////
107
108// MUX1: Pass acc_reg[31:0] at cyc2 of SPU accumulate, otherwise acc_reg[63:32]
109  assign mux1_reg[63:32] = acc_actc2 ? acc_reg[31:0] 
110                                     : acc_reg[63:32] ;
111
112// Bypass mout[31:0] (mul core output) of MAC1 at cyc5 when the lower 32-bit
113//        are ready but not lateched into acc_reg yet.
114//
115//  MAC1: cyc1  |cyc2   |cyc3   |       cyc4    |       cyc5    |       cyc6
116//              |       |       |               |  mout[31:0]   |  acc_reg[128:0]       
117//              |       |       |               |  bypass       |  latched out
118//     
119//  MAC2:                       |       cyc1    |       cyc2    |       
120//                              |               |  ACCUM from   |       
121//                              |               |  mout[31:0]   |
122//                                             
123  assign mux1_mou[63:32] = (acc_actc2 & acc_actc5) ? mout[31:0]
124                                                   : mout[63:32] ;
125
126// MUX2: Immediate bypass from mout (output of mul core)
127  assign mux2_reg[96:0]  = acc_imm   ? {mout[128:64],mux1_mou[63:32]}
128                                     : {acc_reg[128:64],mux1_reg[63:32]};
129
130// Enable of accumulate reg input to multipler core
131  assign areg[96:32] = mux2_reg[96:32] & {65{acc_actc3}} ;
132  assign areg[31:0] =  mux2_reg[31:0]  & {32{(acc_actc3 | acc_actc2)}};
133
134
135
136///////////////////////////////////////////////////////////////////////////////
137//////  Multiplier core connection
138///////////////////////////////////////////////////////////////////////////////
139
140  mul64         mulcore(.rs1_l  (~mul_op1_d),
141                        .rs2    (mul_op2_d),
142                        .valid  (valid),
143                        .areg   (areg),
144                        .accreg (acc_reg[135:129]),
145                        .x2     (x2),
146                        .out    (mout),
147                        .rclk   (clk),
148                        .si     (),
149                        .so     (),
150                        .se     (se),
151                        .mul_rst_l (rst_l),
152                        .mul_step  (1'b1)
153                        );
154                       
155///////////////////////////////////////////////////////////////////////////////
156/////   ACCUM register and right shift muxes
157///////////////////////////////////////////////////////////////////////////////
158
159  dff_s         dffshf (.din    (acc_reg_shf),
160                        .clk    (clk),
161                        .q      (acc_reg_shf2),
162                        .se     (se),
163                        .si     (),
164                        .so     ()
165                        );
166
167  assign acc_reg_in  =  acc_reg_shf  ?  {64'b0,acc_reg[135:64]}
168                                     :  mout ;
169
170  assign mul_data_out = acc_reg_shf2 ?  acc_reg[63:0]
171                                     :  mout[63:0]      ;
172
173`ifdef FPGA_SYN_CLK_DFF
174  dffre_s  #(136)  accum  (.din    (acc_reg_in),
175                        .rst    (acc_reg_rst),
176                        .en (acc_reg_enb | acc_reg_rst), .clk(clk), //manually fixed
177                        .q      (acc_reg),
178                        .se     (se),
179                        .si     (),
180                        .so     ()
181                        );
182`else
183  dffr_s  #(136)  accum  (.din    (acc_reg_in),
184                        .rst    (acc_reg_rst),
185                        .clk    (clk_enb1),
186                        .q      (acc_reg),
187                        .se     (se),
188                        .si     (),
189                        .so     ()
190                        );
191`endif
192
193`ifdef FPGA_SYN_CLK_EN
194`else
195  clken_buf     ckbuf_1(.clk(clk_enb1), .rclk(clk), .enb_l(~(acc_reg_enb | acc_reg_rst)), .tmb_l(~se));
196`endif
197
198
199  assign bypreg =  byp_imm ? mout[63:0]
200                           : acc_reg[63:0] ;
201
202endmodule 
203
Note: See TracBrowser for help on using the repository browser.