1 |
2 |
thorn_aitc |
//======================================================
|
2 |
|
|
// Aquarius Project
|
3 |
|
|
// SuperH-2 ISA Compatible RISC CPU
|
4 |
|
|
//------------------------------------------------------
|
5 |
|
|
// Module : Multiplier Unit
|
6 |
|
|
//------------------------------------------------------
|
7 |
|
|
// File : mult.v
|
8 |
|
|
// Library : none
|
9 |
|
|
// Description : Multiplier Unit in CPU.
|
10 |
|
|
// Simulator : Icarus Verilog (Cygwin)
|
11 |
|
|
// Synthesizer : Xilinx XST (Windows XP)
|
12 |
|
|
// Author : Thorn Aitch
|
13 |
|
|
//------------------------------------------------------
|
14 |
|
|
// Revision Number : 1
|
15 |
|
|
// Date of Change : 19th August 2002
|
16 |
|
|
// Creator : Thorn Aitch
|
17 |
|
|
// Description : Initial Design
|
18 |
|
|
//------------------------------------------------------
|
19 |
|
|
// Revision Number : 2
|
20 |
|
|
// Date of Change : 30th April 2003
|
21 |
|
|
// Modifier : Thorn Aitch
|
22 |
|
|
// Description : Release Version 1.0
|
23 |
|
|
//======================================================
|
24 |
|
|
// Copyright (C) 2002-2003, Thorn Aitch
|
25 |
|
|
//
|
26 |
|
|
// Designs can be altered while keeping list of
|
27 |
|
|
// modifications "the same as in GNU" No money can
|
28 |
|
|
// be earned by selling the designs themselves, but
|
29 |
|
|
// anyone can get money by selling the implementation
|
30 |
|
|
// of the design, such as ICs based on some cores,
|
31 |
|
|
// boards based on some schematics or Layouts, and
|
32 |
|
|
// even GUI interfaces to text mode drivers.
|
33 |
|
|
// "The same as GPL SW" Any update to the design
|
34 |
|
|
// should be documented and returned to the design.
|
35 |
|
|
// Any derivative work based on the IP should be free
|
36 |
|
|
// under OpenIP License. Derivative work means any
|
37 |
|
|
// update, change or improvement on the design.
|
38 |
|
|
// Any work based on the design can be either made
|
39 |
|
|
// free under OpenIP license or protected by any other
|
40 |
|
|
// license. Work based on the design means any work uses
|
41 |
|
|
// the OpenIP Licensed core as a building black without
|
42 |
|
|
// changing anything on it with any other blocks to
|
43 |
|
|
// produce larger design. There is NO WARRANTY on the
|
44 |
|
|
// functionality or performance of the design on the
|
45 |
|
|
// real hardware implementation.
|
46 |
|
|
// On the other hand, the SuperH-2 ISA (Instruction Set
|
47 |
|
|
// Architecture) executed by Aquarius is rigidly
|
48 |
|
|
// the property of Renesas Corp. Then you have all
|
49 |
|
|
// responsibility to judge if there are not any
|
50 |
|
|
// infringements to Renesas's rights regarding your
|
51 |
|
|
// Aquarius adoption into your design.
|
52 |
|
|
// By adopting Aquarius, the user assumes all
|
53 |
|
|
// responsibility for its use.
|
54 |
|
|
// This project may cause any damages around you, for
|
55 |
|
|
// example, loss of properties, data, money, profits,
|
56 |
|
|
// life, or business etc. By adopting this source,
|
57 |
|
|
// the user assumes all responsibility for its use.
|
58 |
|
|
//======================================================
|
59 |
|
|
|
60 |
|
|
`include "timescale.v"
|
61 |
|
|
`include "defines.v"
|
62 |
|
|
|
63 |
|
|
//****************************
|
64 |
|
|
// Multiply Unit Specification
|
65 |
|
|
//****************************
|
66 |
|
|
// This unit handles following multiplier related operations.
|
67 |
|
|
// DMULS.L
|
68 |
|
|
// DMULU.L
|
69 |
|
|
// MAC.L
|
70 |
|
|
// MAC.W
|
71 |
|
|
// MUL.L
|
72 |
|
|
// MULS.W
|
73 |
|
|
// MULU.W
|
74 |
|
|
// Physical multiplier size is 32bit*16bit->48bit.
|
75 |
|
|
// Then, 32x32 operations are executed in 2 cycles.
|
76 |
|
|
|
77 |
|
|
//*************************************************
|
78 |
|
|
// Module Definition
|
79 |
|
|
//*************************************************
|
80 |
|
|
module mult(
|
81 |
|
|
// system signal
|
82 |
|
|
CLK, RST,
|
83 |
|
|
// command
|
84 |
|
|
SLOT, MULCOM1, MULCOM2, MAC_S, WRMACH, WRMACL,
|
85 |
|
|
// input data
|
86 |
|
|
MACIN1, MACIN2,
|
87 |
|
|
// output data
|
88 |
|
|
MACH, MACL,
|
89 |
|
|
// busy signal
|
90 |
|
|
MAC_BUSY
|
91 |
|
|
);
|
92 |
|
|
|
93 |
|
|
//-------------------
|
94 |
|
|
// Module I/O Signals
|
95 |
|
|
//-------------------
|
96 |
|
|
input CLK; // clock
|
97 |
|
|
input RST; // reset
|
98 |
|
|
input SLOT; // cpu pipe slot
|
99 |
|
|
input MULCOM1; // M1 latch command
|
100 |
|
|
input [7:0] MULCOM2; // M2 latch and mult engage command
|
101 |
|
|
// NOP 0 0000000 00
|
102 |
|
|
// DMULS.L 1 0111101 BD
|
103 |
|
|
// DMULU.L 1 0110101 B5
|
104 |
|
|
// MAC.L 1 0001111 8F
|
105 |
|
|
// MAC.W 1 1001111 CF
|
106 |
|
|
// MUL.L 1 0000111 87
|
107 |
|
|
// MULS.W 1 0101111 AF
|
108 |
|
|
// MULU.W 1 0101110 AE
|
109 |
|
|
input MAC_S; // S-bit in SR
|
110 |
|
|
input WRMACH, WRMACL;// write MACH and MACL directly from data path
|
111 |
|
|
input [31:0] MACIN1; // input data 1
|
112 |
|
|
input [31:0] MACIN2; // input data 2
|
113 |
|
|
output [31:0] MACH; // output MACH
|
114 |
|
|
output [31:0] MACL; // output MACL
|
115 |
|
|
output MAC_BUSY; // busy signal (negate at final operation state)
|
116 |
|
|
|
117 |
|
|
//-----------------
|
118 |
|
|
// Internal Signals
|
119 |
|
|
//-----------------
|
120 |
|
|
reg [31:0] M1; // input data1 latch
|
121 |
|
|
reg [31:0] M2; // input data2 latch
|
122 |
|
|
reg [31:0] MB; // input data 2 buffer to implement continuous MAC.L instruction
|
123 |
|
|
reg SELA; // 0:A=M1, 1:A=MB
|
124 |
|
|
reg [31:0] A; // A=M1 or A=MB (selected by SELA)
|
125 |
|
|
reg [31:0] B; // B=M2
|
126 |
|
|
reg SHIFT; // use lower(0)/upper(1) 16bit of B; use unshifted(0)/16bit-shifted(1) PM
|
127 |
|
|
reg SIGN; // 0:unsigned, 1:signed (multipier operation)
|
128 |
|
|
reg SIZE; // if 32*32 then 1, 16*16 then 0
|
129 |
|
|
reg [30:0] AH; // lower 31bit of A
|
130 |
|
|
reg [15:0] BH; // upper 16bit of B(0) or lower 16bit of B(1)
|
131 |
|
|
reg [46:0] ABH; // output of Multiplier(31x16) (=A * BH) (calculated as unsigned)
|
132 |
|
|
reg [32:0] ABH2; // modified ABH
|
133 |
|
|
reg [31:0] P2; // if signed32*32, ~SHIFT&A[31]&B[31:0], if signed16*16, ~SHIFT&A[31]&{B[15:0]:16'h0000}
|
134 |
|
|
reg [31:0] P3; // if signed32*32, ~SHIFT&B[31]&A[31:0], if signed16*16, ~SHIFT&B[15]&A[31:0]
|
135 |
|
|
reg [31:0] P23; // P2 + P3
|
136 |
|
|
reg [32:0] P23S; // if SIGN, ~P23, else P23
|
137 |
|
|
reg [47:0] PM; // multiplier output (partial result) with sign
|
138 |
|
|
reg [63:0] C; // one of the adder inputs
|
139 |
|
|
reg ZH; // if final result is 16bit, adder input from MACH is forced to zero
|
140 |
|
|
reg [1:0] ADD; // 00:ADD, 10:ADDS48, 11:ADDS32 (adder functions regarding saturation)
|
141 |
|
|
reg [63:0] ADDRESULT; // pure adder result
|
142 |
|
|
reg [63:0] ADDRESULT2; // saturated result
|
143 |
|
|
reg SAT; // whether saturation has occured or not (to or 0001 to MACH)
|
144 |
|
|
reg LATMACH; // latch signal of MACH by state machine
|
145 |
|
|
reg LATMACL; // latch signal of MACL by state machine
|
146 |
|
|
reg [31:0] MACH; // actual MACH
|
147 |
|
|
reg [31:0] MACL; // actual MACL
|
148 |
|
|
reg MAC_BUSY; // busy signal (negate at final operation state)
|
149 |
|
|
reg [3:0] STATE; // control state
|
150 |
|
|
reg [3:0] NEXTSTATE; // next state
|
151 |
|
|
reg MAC_DISPATCH; // mult can accept next new operation
|
152 |
|
|
|
153 |
|
|
//-------------------
|
154 |
|
|
// Main State Machine
|
155 |
|
|
//-------------------
|
156 |
|
|
// state machine F/F
|
157 |
|
|
always @(posedge CLK or posedge RST)
|
158 |
|
|
begin
|
159 |
|
|
if (RST == 1'b1)
|
160 |
|
|
STATE <= `NOP;
|
161 |
|
|
else if (MAC_DISPATCH & SLOT)
|
162 |
|
|
begin
|
163 |
|
|
case(MULCOM2)
|
164 |
|
|
8'h00 : STATE <= `NOP;
|
165 |
|
|
8'hBD : STATE <= `DMULSL;
|
166 |
|
|
8'hB5 : STATE <= `DMULUL;
|
167 |
|
|
8'h8F : if (MAC_S == 1'b0)
|
168 |
|
|
STATE <= `MACL0;
|
169 |
|
|
else
|
170 |
|
|
STATE <= `MACLS;
|
171 |
|
|
8'hCF : if (MAC_S == 1'b0)
|
172 |
|
|
STATE <= `MACW;
|
173 |
|
|
else
|
174 |
|
|
STATE <= `MACWS;
|
175 |
|
|
8'h87 : STATE <= `MULL;
|
176 |
|
|
8'hAF : STATE <= `MULSW;
|
177 |
|
|
8'hAE : STATE <= `MULUW;
|
178 |
|
|
default : STATE <= `NOP;
|
179 |
|
|
endcase
|
180 |
|
|
end
|
181 |
|
|
else if (MAC_DISPATCH & ~SLOT)
|
182 |
|
|
STATE <= `NOP;
|
183 |
|
|
else if (~MAC_DISPATCH)
|
184 |
|
|
STATE <= NEXTSTATE;
|
185 |
|
|
end
|
186 |
|
|
|
187 |
|
|
//------------------
|
188 |
|
|
// State Transistion
|
189 |
|
|
//------------------
|
190 |
|
|
// NOP : A=M1, BH=LowerB, unsign MULT, C=PM, > NOP
|
191 |
|
|
//
|
192 |
|
|
// DMULSL : A=M1, BH=LowerB, signed MULT, C=PM, MAC<=ADD > DMULSL2
|
193 |
|
|
// DMULSL2 : A=M1, BH=upperB, signed MULT, C=(PM<<16), MAC<=ADD > NOP
|
194 |
|
|
//
|
195 |
|
|
// DMULUL : A=M1, BH=LowerB, unsign MULT, C=PM, MAC<=ADD > DMULUL2
|
196 |
|
|
// DMULUL2 : A=M1, BH=upperB, unsign MULT, C=(PM<<16), MAC<=ADD > NOP
|
197 |
|
|
//
|
198 |
|
|
// MACL0 : A=MB, BH=LowerB, signed MULT, C=PM, MAC<=ADD > MACL2
|
199 |
|
|
// MACL2 : A=MB, BH=upperB, signed MULT, C=(PM<<16), MAC<=ADD > NOP
|
200 |
|
|
|
201 |
|
|
// MACLS : A=MB, BH=LowerB, signed MULT, C=PM, MAC<=ADDS48 > MACL2
|
202 |
|
|
// MACLS2 : A=MB, BH=upperB, signed MULT, C=(PM<<16), MAC<=ADDS48 > NOP
|
203 |
|
|
|
204 |
|
|
// MACW : A=M1, BH=LowerB, signed MULT, C=PM, MAC<=ADD > NOP
|
205 |
|
|
|
206 |
|
|
// MACWS : A=M1, BH=LowerB, signed MULT, C=PM, MACL<=ADDS32 > NOP
|
207 |
|
|
// if saturate, MACH|=0001
|
208 |
|
|
|
209 |
|
|
// MULL : A=M1, BH=LowerB, signed MULT, C=PM, MACL<=ADD > MULL2
|
210 |
|
|
// MULL2 : A=M1, BH=upperB, signed MULT, C=(PM<<16), MACL<=ADD > NOP
|
211 |
|
|
|
212 |
|
|
// MULSW : A=M1, BH=LowerB, signed MULT, C=PM, MACL<=ADD > NOP
|
213 |
|
|
|
214 |
|
|
// MULUW : A=M1, BH=LowerB, unsign MULT, C=PM, MACL<=ADD > NOP
|
215 |
|
|
|
216 |
|
|
always @(STATE or SLOT or MULCOM2 or MAC_S)
|
217 |
|
|
begin
|
218 |
|
|
case (STATE)
|
219 |
|
|
`NOP :begin
|
220 |
|
|
{SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_000_00_000;
|
221 |
|
|
MAC_BUSY <= 1'b0;
|
222 |
|
|
MAC_DISPATCH <= 1'b1;
|
223 |
|
|
NEXTSTATE <= `NOP;
|
224 |
|
|
end
|
225 |
|
|
`DMULSL :begin
|
226 |
|
|
{SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_011_00_110;
|
227 |
|
|
MAC_BUSY <= 1'b1;
|
228 |
|
|
MAC_DISPATCH <= 1'b0;
|
229 |
|
|
NEXTSTATE <= `DMULSL2;
|
230 |
|
|
end
|
231 |
|
|
`DMULSL2:begin
|
232 |
|
|
{SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_111_00_110;
|
233 |
|
|
MAC_BUSY <= 1'b0;
|
234 |
|
|
MAC_DISPATCH <= 1'b1;
|
235 |
|
|
NEXTSTATE <= `NOP;
|
236 |
|
|
end
|
237 |
|
|
`DMULUL :begin
|
238 |
|
|
{SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_001_00_110;
|
239 |
|
|
MAC_BUSY <= 1'b1;
|
240 |
|
|
MAC_DISPATCH <= 1'b0;
|
241 |
|
|
NEXTSTATE <= `DMULUL2;
|
242 |
|
|
end
|
243 |
|
|
`DMULUL2:begin
|
244 |
|
|
{SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_101_00_110;
|
245 |
|
|
MAC_BUSY <= 1'b0;
|
246 |
|
|
MAC_DISPATCH <= 1'b1;
|
247 |
|
|
NEXTSTATE <= `NOP;
|
248 |
|
|
end
|
249 |
|
|
`MACL0 :begin
|
250 |
|
|
{SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b1_011_00_110;
|
251 |
|
|
MAC_BUSY <= 1'b1;
|
252 |
|
|
MAC_DISPATCH <= 1'b0;
|
253 |
|
|
NEXTSTATE <= `MACL2;
|
254 |
|
|
end
|
255 |
|
|
`MACL2 :begin
|
256 |
|
|
{SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b1_111_00_110;
|
257 |
|
|
MAC_BUSY <= 1'b0;
|
258 |
|
|
MAC_DISPATCH <= 1'b1;
|
259 |
|
|
NEXTSTATE <= `NOP;
|
260 |
|
|
end
|
261 |
|
|
`MACLS :begin
|
262 |
|
|
{SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b1_011_10_110;
|
263 |
|
|
MAC_BUSY <= 1'b1;
|
264 |
|
|
MAC_DISPATCH <= 1'b0;
|
265 |
|
|
NEXTSTATE <= `MACLS2;
|
266 |
|
|
end
|
267 |
|
|
`MACLS2 :begin
|
268 |
|
|
{SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b1_111_10_110;
|
269 |
|
|
MAC_BUSY <= 1'b0;
|
270 |
|
|
MAC_DISPATCH <= 1'b1;
|
271 |
|
|
NEXTSTATE <= `NOP;
|
272 |
|
|
end
|
273 |
|
|
`MACW :begin
|
274 |
|
|
{SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_010_00_110;
|
275 |
|
|
MAC_BUSY <= 1'b1;
|
276 |
|
|
MAC_DISPATCH <= 1'b1;
|
277 |
|
|
NEXTSTATE <= `NOP;
|
278 |
|
|
end
|
279 |
|
|
`MACWS :begin
|
280 |
|
|
{SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_010_11_011;
|
281 |
|
|
MAC_BUSY <= 1'b0;
|
282 |
|
|
MAC_DISPATCH <= 1'b1;
|
283 |
|
|
NEXTSTATE <= `NOP;
|
284 |
|
|
end
|
285 |
|
|
`MULL :begin
|
286 |
|
|
{SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_011_00_011;
|
287 |
|
|
MAC_BUSY <= 1'b1;
|
288 |
|
|
MAC_DISPATCH <= 1'b0;
|
289 |
|
|
NEXTSTATE <= `MULL2;
|
290 |
|
|
end
|
291 |
|
|
`MULL2 :begin
|
292 |
|
|
{SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_111_00_011;
|
293 |
|
|
MAC_BUSY <= 1'b0;
|
294 |
|
|
MAC_DISPATCH <= 1'b1;
|
295 |
|
|
NEXTSTATE <= `NOP;
|
296 |
|
|
end
|
297 |
|
|
`MULSW :begin
|
298 |
|
|
{SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_010_00_011;
|
299 |
|
|
MAC_BUSY <= 1'b0;
|
300 |
|
|
MAC_DISPATCH <= 1'b1;
|
301 |
|
|
NEXTSTATE <= `NOP;
|
302 |
|
|
end
|
303 |
|
|
`MULUW :begin
|
304 |
|
|
{SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_000_00_011;
|
305 |
|
|
MAC_BUSY <= 1'b0;
|
306 |
|
|
MAC_DISPATCH <= 1'b1;
|
307 |
|
|
NEXTSTATE <= `NOP;
|
308 |
|
|
end
|
309 |
|
|
default : begin
|
310 |
|
|
{SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_000_00_000;
|
311 |
|
|
MAC_BUSY <= 1'b0;
|
312 |
|
|
MAC_DISPATCH <= 1'b1;
|
313 |
|
|
NEXTSTATE <= `NOP;
|
314 |
|
|
end
|
315 |
|
|
endcase
|
316 |
|
|
end
|
317 |
|
|
|
318 |
|
|
//-----------------------------------------
|
319 |
|
|
// Data Path
|
320 |
|
|
//-----------------------------------------
|
321 |
|
|
|
322 |
|
|
//---
|
323 |
|
|
// M1
|
324 |
|
|
//---
|
325 |
|
|
always @(posedge CLK)
|
326 |
|
|
begin
|
327 |
|
|
if (SLOT & MULCOM1)
|
328 |
|
|
begin
|
329 |
|
|
M1 <= MACIN1;
|
330 |
|
|
end
|
331 |
|
|
end
|
332 |
|
|
|
333 |
|
|
//-------
|
334 |
|
|
// M2
|
335 |
|
|
// B (=M2)
|
336 |
|
|
//-------
|
337 |
|
|
always @(posedge CLK)
|
338 |
|
|
begin
|
339 |
|
|
if (SLOT & MULCOM2[7])
|
340 |
|
|
begin
|
341 |
|
|
M2 <= MACIN2;
|
342 |
|
|
end
|
343 |
|
|
end
|
344 |
|
|
|
345 |
|
|
always @(M2) B <= M2;
|
346 |
|
|
|
347 |
|
|
//---
|
348 |
|
|
// MB
|
349 |
|
|
//---
|
350 |
|
|
// if SLOT and MULCOM2=MACL, do latch M1.
|
351 |
|
|
always @(posedge CLK)
|
352 |
|
|
begin
|
353 |
|
|
if (SLOT & MULCOM2[7] & (MULCOM2[5:0] == 6'b001111))
|
354 |
|
|
begin
|
355 |
|
|
MB <= M1;
|
356 |
|
|
end
|
357 |
|
|
end
|
358 |
|
|
|
359 |
|
|
//--------
|
360 |
|
|
//Select A
|
361 |
|
|
//--------
|
362 |
|
|
always @(SELA or M1 or MB)
|
363 |
|
|
begin
|
364 |
|
|
if (SELA)
|
365 |
|
|
A <= MB;
|
366 |
|
|
else
|
367 |
|
|
A <= M1;
|
368 |
|
|
end
|
369 |
|
|
|
370 |
|
|
//---------------------------------------
|
371 |
|
|
// lower 31bit of A (input to Multiplier)
|
372 |
|
|
//---------------------------------------
|
373 |
|
|
always @(A or SIZE)
|
374 |
|
|
begin
|
375 |
|
|
if (SIZE == 1'b0)
|
376 |
|
|
AH <= {16'h0000,A[14:0]};
|
377 |
|
|
else
|
378 |
|
|
AH <= A[30:0];
|
379 |
|
|
end
|
380 |
|
|
|
381 |
|
|
//---------------------------------------
|
382 |
|
|
// upper/lower of B (input to Multiplier)
|
383 |
|
|
//---------------------------------------
|
384 |
|
|
always @(B or SHIFT or SIZE)
|
385 |
|
|
begin
|
386 |
|
|
if (SIZE == 1'b0)
|
387 |
|
|
BH <= {1'b0,B[14:0]};
|
388 |
|
|
else if (SHIFT == 1'b0)
|
389 |
|
|
BH <= B[15:0];
|
390 |
|
|
else
|
391 |
|
|
BH <= {1'b0,B[30:16]};
|
392 |
|
|
end
|
393 |
|
|
|
394 |
|
|
//-----------
|
395 |
|
|
// Multiplier
|
396 |
|
|
//----------
|
397 |
|
|
always @(AH or BH)
|
398 |
|
|
begin
|
399 |
|
|
ABH[46:0] <= AH[30:0] * BH[15:0]; // 31bit * 16bit -> 47bit
|
400 |
|
|
end
|
401 |
|
|
|
402 |
|
|
//---
|
403 |
|
|
// PM
|
404 |
|
|
//---
|
405 |
|
|
always @(SHIFT or SIZE or A or B)
|
406 |
|
|
begin
|
407 |
|
|
if (SHIFT)
|
408 |
|
|
begin
|
409 |
|
|
P2 <= {1'b0, (A[31])? B[30:0]:31'h00000000};
|
410 |
|
|
P3 <= {1'b0, (B[31])? A[30:0]:31'h00000000};
|
411 |
|
|
end
|
412 |
|
|
else if(~SIZE)
|
413 |
|
|
begin
|
414 |
|
|
P2 <= {17'h00000, (A[15])? B[14:0]:15'h0000};
|
415 |
|
|
P3 <= {17'h00000, (B[15])? A[14:0]:15'h0000};
|
416 |
|
|
end
|
417 |
|
|
else
|
418 |
|
|
begin
|
419 |
|
|
P2 <= 32'h00000000;
|
420 |
|
|
P3 <= 32'h00000000;
|
421 |
|
|
end
|
422 |
|
|
end
|
423 |
|
|
|
424 |
|
|
always @(P2 or P3)
|
425 |
|
|
begin
|
426 |
|
|
P23 <= P2 + P3;
|
427 |
|
|
end
|
428 |
|
|
|
429 |
|
|
always @(ABH or SHIFT or SIZE or A or B)
|
430 |
|
|
begin
|
431 |
|
|
if (SIZE == 1'b0)
|
432 |
|
|
ABH2 <= {17'h00000,(A[15] & B[15]),ABH[29:15]};
|
433 |
|
|
else if (SHIFT == 1'b0)
|
434 |
|
|
ABH2 <= {1'b0, ABH[46:15]};
|
435 |
|
|
else
|
436 |
|
|
ABH2 <= {1'b0,(A[31] & B[31]),ABH[45:15]};
|
437 |
|
|
end
|
438 |
|
|
|
439 |
|
|
always @(P23 or SIGN)
|
440 |
|
|
begin
|
441 |
|
|
if (SIGN == 1'b0)
|
442 |
|
|
P23S <= {1'b0, P23};
|
443 |
|
|
else
|
444 |
|
|
P23S <= {1'b1,~P23};
|
445 |
|
|
end
|
446 |
|
|
|
447 |
|
|
always @(P23S or ABH or ABH2 or SIGN)
|
448 |
|
|
begin
|
449 |
|
|
PM[47:15] <= ABH2[32:0] + P23S + SIGN;
|
450 |
|
|
PM[14: 0] <= ABH[14: 0];
|
451 |
|
|
end
|
452 |
|
|
|
453 |
|
|
//---------
|
454 |
|
|
// Select C
|
455 |
|
|
//---------
|
456 |
|
|
always @(PM or SHIFT or SIZE)
|
457 |
|
|
begin
|
458 |
|
|
if (SHIFT == 1'b0)
|
459 |
|
|
if (~SIZE & PM[47])
|
460 |
|
|
C <= {16'hffff, PM};
|
461 |
|
|
else
|
462 |
|
|
C <= {16'h0000, PM};
|
463 |
|
|
else
|
464 |
|
|
C <= {PM, 16'h0000};
|
465 |
|
|
end
|
466 |
|
|
|
467 |
|
|
//-------------------------------------
|
468 |
|
|
// 64bit ADDER with Satulating function
|
469 |
|
|
//-------------------------------------
|
470 |
|
|
//
|
471 |
|
|
// Essential of Saturate Operation [ MAC[64] + C[64] ]
|
472 |
|
|
//
|
473 |
|
|
// +S | Left plane shows value of MAC.
|
474 |
|
|
// \ | "+S" is + side saturate value (ex.00007FFF).
|
475 |
|
|
// \ <P> "-S" is - side saturate value (ex.FFFF8000).
|
476 |
|
|
// <P'> \ | Addition of plus C rotates MAC value counterclockwise.
|
477 |
|
|
// \ | Addition of minus C rotates MAC value clockwise.
|
478 |
|
|
// 7F.. \| 00..
|
479 |
|
|
// ------------------- Region<M'> : MAC=80000000~FFFF7FFF
|
480 |
|
|
// 80.. /| FF.. Region<M > : MAC=FFFF8000~FFFFFFFF
|
481 |
|
|
// / | Region<P > : MAC=00000000~00007FFF
|
482 |
|
|
// <M'> / | Region<P'> : MAC=00008000~7FFFFFFF
|
483 |
|
|
// / <M>
|
484 |
|
|
// / | Note that initial MAC value may be in any region.
|
485 |
|
|
// -S | And value C may also be 00000000~FFFFFFFF.
|
486 |
|
|
//
|
487 |
|
|
// ===========================================
|
488 |
|
|
// Initial_MAC Rotation(C) MAC+C Result_MAC
|
489 |
|
|
// ===========================================
|
490 |
|
|
// P + P OK
|
491 |
|
|
// P + P' 00007FFF
|
492 |
|
|
// P + M' 00007FFF
|
493 |
|
|
// P + M 00007FFF
|
494 |
|
|
// -------------------------------------------
|
495 |
|
|
// P' + P 00007FFF Impossible
|
496 |
|
|
// P' + P' 00007FFF
|
497 |
|
|
// P' + M' 00007FFF
|
498 |
|
|
// P' + M 00007FFF
|
499 |
|
|
// -------------------------------------------
|
500 |
|
|
// M' + P OK
|
501 |
|
|
// M' + P' 00007FFF Imposible
|
502 |
|
|
// M' + M' FFFF8000
|
503 |
|
|
// M' + M OK
|
504 |
|
|
// -------------------------------------------
|
505 |
|
|
// M + P OK
|
506 |
|
|
// M + P' 00007FFF
|
507 |
|
|
// M + M' 00007FFF Impossible
|
508 |
|
|
// M + M OK
|
509 |
|
|
// ===========================================
|
510 |
|
|
// P - P OK
|
511 |
|
|
// P - P' FFFF8000 Impossible
|
512 |
|
|
// P - M' FFFF8000
|
513 |
|
|
// P - M OK
|
514 |
|
|
// -------------------------------------------
|
515 |
|
|
// P' - P OK
|
516 |
|
|
// P' - P' 00007FFF
|
517 |
|
|
// P' - M' FFFF8000 Impossible
|
518 |
|
|
// P' - M OK
|
519 |
|
|
// -------------------------------------------
|
520 |
|
|
// M' - P FFFF8000
|
521 |
|
|
// M' - P' FFFF8000
|
522 |
|
|
// M' - M' FFFF8000
|
523 |
|
|
// M' - M FFFF8000 Impossible
|
524 |
|
|
// -------------------------------------------
|
525 |
|
|
// M - P FFFF8000
|
526 |
|
|
// M - P' FFFF8000
|
527 |
|
|
// M - M' FFFF8000
|
528 |
|
|
// M - M OK
|
529 |
|
|
// ===========================================
|
530 |
|
|
|
531 |
|
|
// Again, Compactly...
|
532 |
|
|
// ===========================================
|
533 |
|
|
// Initial_MAC Rotation(C) MAC+C Result_MAC
|
534 |
|
|
// ===========================================
|
535 |
|
|
// P /M +/- P /M OK
|
536 |
|
|
// P /M +/- P'/M' 00007FFF/FFFF8000
|
537 |
|
|
// P /M +/- M'/P' 00007FFF/FFFF8000
|
538 |
|
|
// P /M +/- M /P 00007FFF/FFFF8000
|
539 |
|
|
// -------------------------------------------
|
540 |
|
|
// P'/M' +/- P /M Impossible = Don't care
|
541 |
|
|
// P'/M' +/- P'/M' 00007FFF/FFFF8000
|
542 |
|
|
// P'/M' +/- M'/P' 00007FFF/FFFF8000
|
543 |
|
|
// P'/M' +/- M /P 00007FFF/FFFF8000
|
544 |
|
|
// -------------------------------------------
|
545 |
|
|
// M'/P' +/- P /M OK
|
546 |
|
|
// M'/P' +/- P'/M' Impossible = Don't care
|
547 |
|
|
// M'/P' +/- M'/P' FFFF8000/00007FFF <--caution !
|
548 |
|
|
// M'/P' +/- M /P OK
|
549 |
|
|
// -------------------------------------------
|
550 |
|
|
// M /P +/- P /M OK
|
551 |
|
|
// M /P +/- P'/M' 00007FFF/FFFF8000
|
552 |
|
|
// M /P +/- M'/P' Impossible = Don't care
|
553 |
|
|
// M /P +/- M /P OK
|
554 |
|
|
// ===========================================
|
555 |
|
|
|
556 |
|
|
// Again, Much Compactly...
|
557 |
|
|
// ===========================================
|
558 |
|
|
// Initial_MAC Rotation(C) MAC+C Result_MAC
|
559 |
|
|
// ===========================================
|
560 |
|
|
// P /M +/- P /M OK
|
561 |
|
|
// P /M +/- P'/M' 00007FFF/FFFF8000
|
562 |
|
|
// P /M +/- - /+ 00007FFF/FFFF8000
|
563 |
|
|
// -------------------------------------------
|
564 |
|
|
// P'/M' +/- P /M Impossible = Don't care
|
565 |
|
|
// P'/M' +/- P'/M' 00007FFF/FFFF8000
|
566 |
|
|
// P'/M' +/- - /+ 00007FFF/FFFF8000
|
567 |
|
|
// -------------------------------------------
|
568 |
|
|
// M'/P' +/- P /M OK
|
569 |
|
|
// - /+ +/- M'/P' FFFF8000/00007FFF <--caution !
|
570 |
|
|
// M'/P' +/- M /P OK
|
571 |
|
|
// -------------------------------------------
|
572 |
|
|
// M /P +/- P /M OK
|
573 |
|
|
// - /+ +/- P'/M' 00007FFF/FFFF8000
|
574 |
|
|
// M /P +/- M /P OK
|
575 |
|
|
// ===========================================
|
576 |
|
|
|
577 |
|
|
// Again, Much Compactly...
|
578 |
|
|
// ===========================================
|
579 |
|
|
// Initial_MAC Rotation(C) MAC+C Result_MAC
|
580 |
|
|
// ===========================================
|
581 |
|
|
// + /- +/- P /M OK
|
582 |
|
|
// + /- +/- P'/M' 00007FFF/FFFF8000
|
583 |
|
|
// + /- +/- - /+ 00007FFF/FFFF8000
|
584 |
|
|
// -------------------------------------------
|
585 |
|
|
// - /+ +/- P /M OK
|
586 |
|
|
// - /+ +/- M'/P' FFFF8000/00007FFF <--caution !
|
587 |
|
|
// - /+ +/- M /P OK
|
588 |
|
|
// - /+ +/- P'/M' 00007FFF/FFFF8000
|
589 |
|
|
// ===========================================
|
590 |
|
|
|
591 |
|
|
// Again, Much Compactly...
|
592 |
|
|
// ===========================================
|
593 |
|
|
// Initial_MAC Rotation(C) MAC+C Result_MAC
|
594 |
|
|
// ===========================================
|
595 |
|
|
// * /* +/- P /M OK
|
596 |
|
|
// * /* +/- P'/M' 00007FFF/FFFF8000
|
597 |
|
|
// + /- +/- - /+ 00007FFF/FFFF8000
|
598 |
|
|
// - /+ +/- M'/P' FFFF8000/00007FFF <--caution !
|
599 |
|
|
// - /+ +/- M /P OK
|
600 |
|
|
// ===========================================
|
601 |
|
|
|
602 |
|
|
always @(C or MACH or MACL or ZH)
|
603 |
|
|
begin
|
604 |
|
|
ADDRESULT <= C + {((ZH == 1'b0) ? MACH : 32'h00000000), MACL};
|
605 |
|
|
end
|
606 |
|
|
|
607 |
|
|
reg [1:0] RESULT_REGION48; //00:P, 01:P', 10:M, 11:M'
|
608 |
|
|
reg RESULT_REGION32; //0:P, 1:M, No P'/M' region in case of 32bit saturation.
|
609 |
|
|
always @(ADDRESULT)
|
610 |
|
|
begin
|
611 |
|
|
RESULT_REGION48[1] <= ADDRESULT[63];
|
612 |
|
|
RESULT_REGION32 <= ADDRESULT[31];
|
613 |
|
|
if (ADDRESULT[63] == 1'b0)
|
614 |
|
|
//RESULT_REGION48[0] <= (ADDRESULT[63:47] >= 17'h00001);
|
615 |
|
|
RESULT_REGION48[0] <= (ADDRESULT[63:47] != 17'h00000);
|
616 |
|
|
else
|
617 |
|
|
//RESULT_REGION48[0] <= (ADDRESULT[63:47] <= 17'hFFFFE);
|
618 |
|
|
RESULT_REGION48[0] <= (ADDRESULT[63:47] != 17'hFFFFF);
|
619 |
|
|
end
|
620 |
|
|
|
621 |
|
|
always @(ADDRESULT or C or MACH or MACL or ADD or RESULT_REGION48 or RESULT_REGION32)
|
622 |
|
|
begin
|
623 |
|
|
case(ADD)
|
624 |
|
|
2'b00 : begin // ADD
|
625 |
|
|
ADDRESULT2 <= ADDRESULT;
|
626 |
|
|
SAT <= 1'b0;
|
627 |
|
|
end
|
628 |
|
|
2'b10 : begin // ADDS48
|
629 |
|
|
if (~C[63]) // + rotation
|
630 |
|
|
case ({MACH[31], RESULT_REGION48})
|
631 |
|
|
3'b000 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //+,P
|
632 |
|
|
3'b001 : {ADDRESULT2,SAT} <= {64'h00007FFFFFFFFFFF,1'b1}; //+,P'
|
633 |
|
|
3'b010 : {ADDRESULT2,SAT} <= {64'h00007FFFFFFFFFFF,1'b1}; //+,M
|
634 |
|
|
3'b011 : {ADDRESULT2,SAT} <= {64'h00007FFFFFFFFFFF,1'b1}; //+,M'
|
635 |
|
|
3'b100 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //-,P
|
636 |
|
|
3'b101 : {ADDRESULT2,SAT} <= {64'h00007FFFFFFFFFFF,1'b1}; //-,P'
|
637 |
|
|
3'b110 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //-,M
|
638 |
|
|
3'b111 : {ADDRESULT2,SAT} <= {64'hFFFF800000000000,1'b1}; //-,M'
|
639 |
|
|
default: {ADDRESULT2,SAT} <= {64'hxxxxxxxxxxxxxxxx,1'bx};
|
640 |
|
|
endcase
|
641 |
|
|
else // - rotation
|
642 |
|
|
case ({MACH[31], RESULT_REGION48})
|
643 |
|
|
3'b000 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //+,P
|
644 |
|
|
3'b001 : {ADDRESULT2,SAT} <= {64'h00007FFFFFFFFFFF,1'b1}; //+,P'
|
645 |
|
|
3'b010 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //+,M
|
646 |
|
|
3'b011 : {ADDRESULT2,SAT} <= {64'hFFFF800000000000,1'b1}; //+,M'
|
647 |
|
|
3'b100 : {ADDRESULT2,SAT} <= {64'hFFFF800000000000,1'b1}; //-,P
|
648 |
|
|
3'b101 : {ADDRESULT2,SAT} <= {64'hFFFF800000000000,1'b1}; //-,P'
|
649 |
|
|
3'b110 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //-,M
|
650 |
|
|
3'b111 : {ADDRESULT2,SAT} <= {64'hFFFF800000000000,1'b1}; //-,M'
|
651 |
|
|
default: {ADDRESULT2,SAT} <= {64'hxxxxxxxxxxxxxxxx,1'bx};
|
652 |
|
|
endcase
|
653 |
|
|
end
|
654 |
|
|
2'b11 : begin // ADDS32
|
655 |
|
|
if (~C[31]) // + rotation
|
656 |
|
|
case ({MACL[31], RESULT_REGION32})
|
657 |
|
|
2'b00 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //+,P
|
658 |
|
|
2'b01 : {ADDRESULT2,SAT} <= {64'h000000007FFFFFFF,1'b1}; //+,M
|
659 |
|
|
2'b10 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //-,P
|
660 |
|
|
2'b11 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //-,M
|
661 |
|
|
default: {ADDRESULT2,SAT} <= {64'hxxxxxxxxxxxxxxxx,1'bx};
|
662 |
|
|
endcase
|
663 |
|
|
else // - rotation
|
664 |
|
|
case ({MACL[31], RESULT_REGION32})
|
665 |
|
|
2'b00 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //+,P
|
666 |
|
|
2'b01 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //+,M
|
667 |
|
|
2'b10 : {ADDRESULT2,SAT} <= {64'hFFFFFFFF80000000,1'b1}; //-,P
|
668 |
|
|
2'b11 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //-,M
|
669 |
|
|
default: {ADDRESULT2,SAT} <= {64'hxxxxxxxxxxxxxxxx,1'bx};
|
670 |
|
|
endcase
|
671 |
|
|
end
|
672 |
|
|
default : begin
|
673 |
|
|
ADDRESULT2 <= 64'hxxxxxxxxxxxxxxxx;
|
674 |
|
|
SAT <= 1'b0;
|
675 |
|
|
end
|
676 |
|
|
endcase
|
677 |
|
|
end
|
678 |
|
|
|
679 |
|
|
//-----
|
680 |
|
|
// MACH
|
681 |
|
|
//-----
|
682 |
|
|
// Clear condition of MACH: following command do not clear MACH
|
683 |
|
|
// MAC.L 1 0001111 8F
|
684 |
|
|
// MAC.W 1 1001111 CF
|
685 |
|
|
// MUL.L 1 0000111 87
|
686 |
|
|
// MULS.W 1 0101111 AF
|
687 |
|
|
// MULU.W 1 0101110 AE
|
688 |
|
|
// Should do saturating operation
|
689 |
|
|
always @(posedge CLK)
|
690 |
|
|
begin
|
691 |
|
|
if (SLOT & WRMACH)
|
692 |
|
|
MACH <= MACIN1;
|
693 |
|
|
else if (SLOT & MULCOM2[7]
|
694 |
|
|
& (MULCOM2[5:0] != 6'b001111)
|
695 |
|
|
& (MULCOM2[6:0] != 7'b0000111)
|
696 |
|
|
& (MULCOM2[6:0] != 7'b0101111)
|
697 |
|
|
& (MULCOM2[6:0] != 7'b0101110)
|
698 |
|
|
)
|
699 |
|
|
begin
|
700 |
|
|
MACH <= 32'h00000000;
|
701 |
|
|
end
|
702 |
|
|
else if ((STATE == `MACWS) && (SAT == 1'b1))
|
703 |
|
|
begin
|
704 |
|
|
MACH <= MACH | 32'h00000001;
|
705 |
|
|
end
|
706 |
|
|
else if (LATMACH == 1'b1)
|
707 |
|
|
begin
|
708 |
|
|
MACH <= ADDRESULT2[63:32];
|
709 |
|
|
end
|
710 |
|
|
end
|
711 |
|
|
|
712 |
|
|
//-----
|
713 |
|
|
// MACL
|
714 |
|
|
//-----
|
715 |
|
|
// Clear condition of MACL: following command do not clear MACL
|
716 |
|
|
// MAC.L 1 0001111 8F
|
717 |
|
|
// MAC.W 1 1001111 CF
|
718 |
|
|
always @(posedge CLK)
|
719 |
|
|
begin
|
720 |
|
|
if (SLOT & WRMACL)
|
721 |
|
|
MACL <= MACIN2;
|
722 |
|
|
else if (SLOT & MULCOM2[7] & (MULCOM2[5:0] != 6'b001111))
|
723 |
|
|
begin
|
724 |
|
|
MACL <= 32'h00000000;
|
725 |
|
|
end
|
726 |
|
|
else if (LATMACL == 1'b1)
|
727 |
|
|
begin
|
728 |
|
|
MACL <= ADDRESULT2[31:0];
|
729 |
|
|
end
|
730 |
|
|
end
|
731 |
|
|
|
732 |
|
|
//======================================================
|
733 |
|
|
endmodule
|
734 |
|
|
//======================================================
|