// ============================================================================
|
// ============================================================================
|
// __
|
// __
|
// \\__/ o\ (C) 2017-2019 Robert Finch, Waterloo
|
// \\__/ o\ (C) 2017-2019 Robert Finch, Waterloo
|
// \ __ / All rights reserved.
|
// \ __ / All rights reserved.
|
// \/_// robfinch<remove>@finitron.ca
|
// \/_// robfinch<remove>@finitron.ca
|
// ||
|
// ||
|
//
|
//
|
// FT64_alu.v
|
// FT64_alu.v
|
//
|
//
|
// This source file is free software: you can redistribute it and/or modify
|
// This source file is free software: you can redistribute it and/or modify
|
// it under the terms of the GNU Lesser General Public License as published
|
// it under the terms of the GNU Lesser General Public License as published
|
// by the Free Software Foundation, either version 3 of the License, or
|
// by the Free Software Foundation, either version 3 of the License, or
|
// (at your option) any later version.
|
// (at your option) any later version.
|
//
|
//
|
// This source file is distributed in the hope that it will be useful,
|
// This source file is distributed in the hope that it will be useful,
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
//
|
//
|
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
//
|
//
|
// ============================================================================
|
// ============================================================================
|
//
|
//
|
`include "FT64_defines.vh"
|
`include "FT64_defines.vh"
|
`include "FT64_config.vh"
|
`include "FT64_config.vh"
|
|
|
module FT64_alu(rst, clk, ld, abort, instr, sz, tlb, store, a, b, c, t, pc, Ra, tgt, tgt2, ven, vm,
|
module FT64_alu(rst, clk, ld, abort, instr, sz, store, a, b, c, t, pc, Ra, tgt, tgt2, ven, vm,
|
csr, o, ob, done, idle, excen, exc, thrd, ptrmask, state, mem, shift,
|
csr, o, ob, done, idle, excen, exc, thrd, ptrmask, state, mem, shift,
|
ol, dl, ASID, icl_i, cyc_i, we_i, vadr_i, cyc_o, we_o, padr_o, uncached, tlb_miss,
|
ol, dl
|
exv_o, rdv_o, wrv_o
|
|
`ifdef SUPPORT_BBMS
|
`ifdef SUPPORT_BBMS
|
, pb, cbl, cbu, ro, dbl, dbu, sbl, sbu, en
|
, pb, cbl, cbu, ro, dbl, dbu, sbl, sbu, en
|
`endif
|
`endif
|
);
|
);
|
parameter DBW = 64;
|
parameter DBW = 64;
|
parameter ABW = 64;
|
parameter ABW = 64;
|
parameter BIG = 1'b1;
|
parameter BIG = 1'b1;
|
parameter SUP_VECTOR = 1;
|
parameter SUP_VECTOR = 1;
|
parameter TRUE = 1'b1;
|
parameter TRUE = 1'b1;
|
parameter FALSE = 1'b0;
|
parameter FALSE = 1'b0;
|
parameter PTR = 20'hFFF01;
|
parameter PTR = 20'hFFF01;
|
parameter BASE_SHIFT = 13'd0;
|
parameter BASE_SHIFT = 13'd0;
|
input rst;
|
input rst;
|
input clk;
|
input clk;
|
input ld;
|
input ld;
|
input abort;
|
input abort;
|
input [47:0] instr;
|
input [47:0] instr;
|
input [2:0] sz;
|
input [2:0] sz;
|
input tlb;
|
|
input store;
|
input store;
|
input [63:0] a;
|
input [63:0] a;
|
input [63:0] b;
|
input [63:0] b;
|
input [63:0] c;
|
input [63:0] c;
|
input [63:0] t; // target register value
|
input [63:0] t; // target register value
|
input [31:0] pc;
|
input [31:0] pc;
|
input [11:0] Ra;
|
input [11:0] Ra;
|
input [11:0] tgt;
|
input [11:0] tgt;
|
input [7:0] tgt2;
|
input [7:0] tgt2;
|
input [5:0] ven;
|
input [5:0] ven;
|
input [15:0] vm;
|
input [15:0] vm;
|
input [63:0] csr;
|
input [63:0] csr;
|
output reg [63:0] o;
|
output reg [63:0] o;
|
output reg [63:0] ob;
|
output reg [63:0] ob;
|
output reg done;
|
output reg done;
|
output reg idle;
|
output reg idle;
|
input [4:0] excen;
|
input [4:0] excen;
|
output reg [8:0] exc;
|
output reg [8:0] exc;
|
input thrd;
|
input thrd;
|
input [63:0] ptrmask;
|
input [63:0] ptrmask;
|
input [1:0] state;
|
input [1:0] state;
|
input mem;
|
input mem;
|
input shift;
|
input shift;
|
input [1:0] ol;
|
input [1:0] ol;
|
input [1:0] dl;
|
input [1:0] dl;
|
input [7:0] ASID;
|
|
input icl_i;
|
|
input cyc_i;
|
|
input we_i;
|
|
input [ABW-1:0] vadr_i;
|
|
output cyc_o;
|
|
output we_o;
|
|
output [ABW-1:0] padr_o;
|
|
output uncached;
|
|
output tlb_miss;
|
|
output wrv_o;
|
|
output rdv_o;
|
|
output exv_o;
|
|
`ifdef SUPPORT_BBMS
|
`ifdef SUPPORT_BBMS
|
input [63:0] pb;
|
input [63:0] pb;
|
input [63:0] cbl;
|
input [63:0] cbl;
|
input [63:0] cbu;
|
input [63:0] cbu;
|
input [63:0] ro;
|
input [63:0] ro;
|
input [63:0] dbl;
|
input [63:0] dbl;
|
input [63:0] dbu;
|
input [63:0] dbu;
|
input [63:0] sbl;
|
input [63:0] sbl;
|
input [63:0] sbu;
|
input [63:0] sbu;
|
input [63:0] en;
|
input [63:0] en;
|
`endif
|
`endif
|
|
|
parameter byt = 3'd0;
|
parameter byt = 3'd0;
|
parameter char = 3'd1;
|
parameter char = 3'd1;
|
parameter half = 3'd2;
|
parameter half = 3'd2;
|
parameter word = 3'd3;
|
parameter word = 3'd3;
|
parameter byt_para = 3'd4;
|
parameter byt_para = 3'd4;
|
parameter char_para = 3'd5;
|
parameter char_para = 3'd5;
|
parameter half_para = 3'd6;
|
parameter half_para = 3'd6;
|
parameter word_para = 3'd7;
|
parameter word_para = 3'd7;
|
|
|
integer n;
|
integer n;
|
|
|
reg adrDone, adrIdle;
|
reg adrDone, adrIdle;
|
reg [63:0] usa; // unsegmented address
|
reg [63:0] usa; // unsegmented address
|
`ifndef SUPPORT_BBMS
|
`ifndef SUPPORT_BBMS
|
reg [63:0] pb = 64'h0;
|
reg [63:0] pb = 64'h0;
|
`endif
|
`endif
|
reg [63:0] addro;
|
reg [63:0] addro;
|
reg [63:0] adr; // load / store address
|
reg [63:0] adr; // load / store address
|
reg [63:0] shift8;
|
reg [63:0] shift8;
|
|
|
wire [7:0] a8 = a[7:0];
|
wire [7:0] a8 = a[7:0];
|
wire [15:0] a16 = a[15:0];
|
wire [15:0] a16 = a[15:0];
|
wire [31:0] a32 = a[31:0];
|
wire [31:0] a32 = a[31:0];
|
wire [7:0] b8 = b[7:0];
|
wire [7:0] b8 = b[7:0];
|
wire [15:0] b16 = b[15:0];
|
wire [15:0] b16 = b[15:0];
|
wire [31:0] b32 = b[31:0];
|
wire [31:0] b32 = b[31:0];
|
wire [63:0] orb = instr[6] ? {34'd0,b[29:0]} : {50'd0,b[13:0]};
|
wire [63:0] orb = instr[6] ? {34'd0,b[29:0]} : {50'd0,b[13:0]};
|
wire [63:0] andb = b;//((instr[6]==1'b1) ? {34'h3FFFFFFFF,b[29:0]} : {50'h3FFFFFFFFFFFF,b[13:0]});
|
wire [63:0] andb = b;//((instr[6]==1'b1) ? {34'h3FFFFFFFF,b[29:0]} : {50'h3FFFFFFFFFFFF,b[13:0]});
|
|
|
wire [21:0] qimm = instr[39:18];
|
wire [21:0] qimm = instr[39:18];
|
wire [63:0] imm = {{45{instr[39]}},instr[39:21]};
|
wire [63:0] imm = {{45{instr[39]}},instr[39:21]};
|
wire [DBW-1:0] divq, rem;
|
wire [DBW-1:0] divq, rem;
|
wire divByZero;
|
wire divByZero;
|
wire [15:0] prod80, prod81, prod82, prod83, prod84, prod85, prod86, prod87;
|
wire [15:0] prod80, prod81, prod82, prod83, prod84, prod85, prod86, prod87;
|
wire [31:0] prod160, prod161, prod162, prod163;
|
wire [31:0] prod160, prod161, prod162, prod163;
|
wire [63:0] prod320, prod321;
|
wire [63:0] prod320, prod321;
|
wire [DBW*2-1:0] prod;
|
wire [DBW*2-1:0] prod;
|
wire mult_done8, mult_idle8, div_done8, div_idle8;
|
wire mult_done8, mult_idle8, div_done8, div_idle8;
|
wire mult_done80, mult_idle80, div_done80, div_idle80;
|
wire mult_done80, mult_idle80, div_done80, div_idle80;
|
wire mult_done81, mult_idle81, div_done81, div_idle81;
|
wire mult_done81, mult_idle81, div_done81, div_idle81;
|
wire mult_done82, mult_idle82, div_done82, div_idle82;
|
wire mult_done82, mult_idle82, div_done82, div_idle82;
|
wire mult_done83, mult_idle83, div_done83, div_idle83;
|
wire mult_done83, mult_idle83, div_done83, div_idle83;
|
wire mult_done84, mult_idle84, div_done84, div_idle84;
|
wire mult_done84, mult_idle84, div_done84, div_idle84;
|
wire mult_done85, mult_idle85, div_done85, div_idle85;
|
wire mult_done85, mult_idle85, div_done85, div_idle85;
|
wire mult_done86, mult_idle86, div_done86, div_idle86;
|
wire mult_done86, mult_idle86, div_done86, div_idle86;
|
wire mult_done87, mult_idle87, div_done87, div_idle87;
|
wire mult_done87, mult_idle87, div_done87, div_idle87;
|
wire mult_done16, mult_idle16, div_done16, div_idle16;
|
wire mult_done16, mult_idle16, div_done16, div_idle16;
|
wire mult_done160, mult_idle160, div_done160, div_idle160;
|
wire mult_done160, mult_idle160, div_done160, div_idle160;
|
wire mult_done161, mult_idle161, div_done161, div_idle161;
|
wire mult_done161, mult_idle161, div_done161, div_idle161;
|
wire mult_done162, mult_idle162, div_done162, div_idle162;
|
wire mult_done162, mult_idle162, div_done162, div_idle162;
|
wire mult_done163, mult_idle163, div_done163, div_idle163;
|
wire mult_done163, mult_idle163, div_done163, div_idle163;
|
wire mult_done320, mult_idle320, div_done320, div_idle320;
|
wire mult_done320, mult_idle320, div_done320, div_idle320;
|
wire mult_done321, mult_idle321, div_done321, div_idle321;
|
wire mult_done321, mult_idle321, div_done321, div_idle321;
|
wire mult_done, mult_idle, div_done, div_idle;
|
wire mult_done, mult_idle, div_done, div_idle;
|
wire aslo;
|
wire aslo;
|
wire [6:0] clzo,cloo,cpopo;
|
wire [6:0] clzo,cloo,cpopo;
|
wire [63:0] shftho;
|
wire [63:0] shftho;
|
reg [63:0] shift9;
|
reg [63:0] shift9;
|
|
|
function IsLoad;
|
function IsLoad;
|
input [47:0] isn;
|
input [47:0] isn;
|
case(isn[`INSTRUCTION_OP])
|
case(isn[`INSTRUCTION_OP])
|
`MEMNDX:
|
`MEMNDX:
|
if (isn[`INSTRUCTION_L2]==2'b00)
|
if (isn[`INSTRUCTION_L2]==2'b00)
|
IsLoad = !isn[31];
|
IsLoad = !isn[31];
|
else
|
else
|
IsLoad = FALSE;
|
IsLoad = FALSE;
|
`LB: IsLoad = TRUE;
|
`LB: IsLoad = TRUE;
|
`LBU: IsLoad = TRUE;
|
`LBU: IsLoad = TRUE;
|
`Lx: IsLoad = TRUE;
|
`Lx: IsLoad = TRUE;
|
`LxU: IsLoad = TRUE;
|
`LxU: IsLoad = TRUE;
|
`LWR: IsLoad = TRUE;
|
`LWR: IsLoad = TRUE;
|
`LV: IsLoad = TRUE;
|
`LV: IsLoad = TRUE;
|
`LVx: IsLoad = TRUE;
|
`LVx: IsLoad = TRUE;
|
`LVxU: IsLoad = TRUE;
|
`LVxU: IsLoad = TRUE;
|
default: IsLoad = FALSE;
|
default: IsLoad = FALSE;
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
function IsMul;
|
function IsMul;
|
input [47:0] isn;
|
input [47:0] isn;
|
case(isn[`INSTRUCTION_OP])
|
case(isn[`INSTRUCTION_OP])
|
`IVECTOR:
|
`IVECTOR:
|
case(isn[`INSTRUCTION_S2])
|
case(isn[`INSTRUCTION_S2])
|
`VMUL,`VMULS: IsMul = TRUE;
|
`VMUL,`VMULS: IsMul = TRUE;
|
default: IsMul = FALSE;
|
default: IsMul = FALSE;
|
endcase
|
endcase
|
`R2:
|
`R2:
|
case(isn[`INSTRUCTION_S2])
|
case(isn[`INSTRUCTION_S2])
|
`MULU,`MULSU,`MUL: IsMul = TRUE;
|
`MULU,`MULSU,`MUL: IsMul = TRUE;
|
`MULUH,`MULSUH,`MULH: IsMul = TRUE;
|
`MULUH,`MULSUH,`MULH: IsMul = TRUE;
|
`FXMUL: IsMul = TRUE;
|
`FXMUL: IsMul = TRUE;
|
default: IsMul = FALSE;
|
default: IsMul = FALSE;
|
endcase
|
endcase
|
`MULUI,`MULI: IsMul = TRUE;
|
`MULUI,`MULI: IsMul = TRUE;
|
default: IsMul = FALSE;
|
default: IsMul = FALSE;
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
function IsDivmod;
|
function IsDivmod;
|
input [47:0] isn;
|
input [47:0] isn;
|
case(isn[`INSTRUCTION_OP])
|
case(isn[`INSTRUCTION_OP])
|
`IVECTOR:
|
`IVECTOR:
|
case(isn[`INSTRUCTION_S2])
|
case(isn[`INSTRUCTION_S2])
|
`VDIV,`VDIVS: IsDivmod = TRUE;
|
`VDIV,`VDIVS: IsDivmod = TRUE;
|
default: IsDivmod = FALSE;
|
default: IsDivmod = FALSE;
|
endcase
|
endcase
|
`R2:
|
`R2:
|
case(isn[`INSTRUCTION_S2])
|
case(isn[`INSTRUCTION_S2])
|
`DIVU,`DIVSU,`DIV: IsDivmod = TRUE;
|
`DIVU,`DIVSU,`DIV: IsDivmod = TRUE;
|
`MODU,`MODSU,`MOD: IsDivmod = TRUE;
|
`MODU,`MODSU,`MOD: IsDivmod = TRUE;
|
default: IsDivmod = FALSE;
|
default: IsDivmod = FALSE;
|
endcase
|
endcase
|
`DIVUI,`DIVI,`MODI: IsDivmod = TRUE;
|
`DIVUI,`DIVI,`MODI: IsDivmod = TRUE;
|
default: IsDivmod = FALSE;
|
default: IsDivmod = FALSE;
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
function IsSgn;
|
function IsSgn;
|
input [47:0] isn;
|
input [47:0] isn;
|
case(isn[`INSTRUCTION_OP])
|
case(isn[`INSTRUCTION_OP])
|
`IVECTOR:
|
`IVECTOR:
|
case(isn[`INSTRUCTION_S2])
|
case(isn[`INSTRUCTION_S2])
|
`VMUL,`VMULS,`VDIV,`VDIVS: IsSgn = TRUE;
|
`VMUL,`VMULS,`VDIV,`VDIVS: IsSgn = TRUE;
|
default: IsSgn = FALSE;
|
default: IsSgn = FALSE;
|
endcase
|
endcase
|
`R2:
|
`R2:
|
case(isn[`INSTRUCTION_S2])
|
case(isn[`INSTRUCTION_S2])
|
`MUL,`DIV,`MOD,`MULH: IsSgn = TRUE;
|
`MUL,`DIV,`MOD,`MULH: IsSgn = TRUE;
|
`FXMUL: IsSgn = TRUE;
|
`FXMUL: IsSgn = TRUE;
|
default: IsSgn = FALSE;
|
default: IsSgn = FALSE;
|
endcase
|
endcase
|
`MULI,`DIVI,`MODI: IsSgn = TRUE;
|
`MULI,`DIVI,`MODI: IsSgn = TRUE;
|
default: IsSgn = FALSE;
|
default: IsSgn = FALSE;
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
function IsSgnus;
|
function IsSgnus;
|
input [47:0] isn;
|
input [47:0] isn;
|
case(isn[`INSTRUCTION_OP])
|
case(isn[`INSTRUCTION_OP])
|
`R2:
|
`R2:
|
case(isn[`INSTRUCTION_S2])
|
case(isn[`INSTRUCTION_S2])
|
`MULSU,`MULSUH,`DIVSU,`MODSU: IsSgnus = TRUE;
|
`MULSU,`MULSUH,`DIVSU,`MODSU: IsSgnus = TRUE;
|
default: IsSgnus = FALSE;
|
default: IsSgnus = FALSE;
|
endcase
|
endcase
|
default: IsSgnus = FALSE;
|
default: IsSgnus = FALSE;
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
function IsShiftAndOp;
|
function IsShiftAndOp;
|
input [47:0] isn;
|
input [47:0] isn;
|
if (isn[`INSTRUCTION_L2]==2'b01) begin
|
if (isn[`INSTRUCTION_L2]==2'b01) begin
|
case(isn[`INSTRUCTION_OP])
|
case(isn[`INSTRUCTION_OP])
|
`R2:
|
`R2:
|
case(isn[47:42])
|
case(isn[47:42])
|
`SHIFTR: IsShiftAndOp = TRUE;
|
`SHIFTR: IsShiftAndOp = TRUE;
|
default: IsShiftAndOp = FALSE;
|
default: IsShiftAndOp = FALSE;
|
endcase
|
endcase
|
default: IsShiftAndOp = FALSE;
|
default: IsShiftAndOp = FALSE;
|
endcase
|
endcase
|
end
|
end
|
else
|
else
|
IsShiftAndOp = FALSE;
|
IsShiftAndOp = FALSE;
|
endfunction
|
endfunction
|
|
|
wire [63:0] bfout,shfto;
|
wire [63:0] bfout,shfto;
|
wire [63:0] shftob;
|
wire [63:0] shftob;
|
wire [63:0] shftco;
|
wire [63:0] shftco;
|
reg [63:0] shift10;
|
reg [63:0] shift10;
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
shift9 <= shift8;
|
shift9 <= shift8;
|
always @*
|
always @*
|
case (instr[41:36])
|
case (instr[41:36])
|
`ADD: shift10 <= shift9 + c;
|
`ADD: shift10 <= shift9 + c;
|
`SUB: shift10 <= shift9 - c;
|
`SUB: shift10 <= shift9 - c;
|
`AND: shift10 <= shift9 & c;
|
`AND: shift10 <= shift9 & c;
|
`OR: shift10 <= shift9 | c;
|
`OR: shift10 <= shift9 | c;
|
`XOR: shift10 <= shift9 ^ c;
|
`XOR: shift10 <= shift9 ^ c;
|
6'h20: shift10 <= ~shift9; // COM
|
6'h20: shift10 <= ~shift9; // COM
|
6'h21: shift10 <= !shift9; // NOT
|
6'h21: shift10 <= !shift9; // NOT
|
default: shift10 <= shift9;
|
default: shift10 <= shift9;
|
endcase
|
endcase
|
|
|
wire tlb_done, tlb_idle;
|
|
wire [DBW-1:0] tlbo;
|
|
|
|
`ifdef SUPPORT_TLB
|
|
FT64_TLB utlb1 (
|
|
.rst(rst),
|
|
.clk(clk),
|
|
.ld(ld & tlb),
|
|
.done(tlb_done),
|
|
.idle(tlb_idle),
|
|
.ol(ol),
|
|
.ASID(ASID),
|
|
.op(instr[25:22]),
|
|
.regno(instr[21:18]),
|
|
.dati(a),
|
|
.dato(tlbo),
|
|
.uncached(uncached),
|
|
.icl_i(icl_i),
|
|
.cyc_i(cyc_i),
|
|
.we_i(we_i),
|
|
.vadr_i(vadr_i),
|
|
.cyc_o(cyc_o),
|
|
.we_o(we_o),
|
|
.padr_o(padr_o),
|
|
.TLBMiss(tlb_miss),
|
|
.wrv_o(wrv_o),
|
|
.rdv_o(rdv_o),
|
|
.exv_o(exv_o),
|
|
.HTLBVirtPageo()
|
|
);
|
|
`else
|
|
assign tlbo = 64'hDEADDEADDEADDEAD;
|
|
assign uncached = 1'b0;
|
|
assign padr_o = vadr_i;
|
|
assign cyc_o = cyc_i;
|
|
assign we_o = we_i;
|
|
assign tlb_miss = 1'b0;
|
|
assign wrv_o = 1'b0;
|
|
assign rdv_o = 1'b0;
|
|
assign exv_o = 1'b0;
|
|
`endif
|
|
|
|
FT64_bitfield #(DBW) ubf1
|
FT64_bitfield #(DBW) ubf1
|
(
|
(
|
.inst(instr),
|
.inst(instr),
|
.a(a),
|
.a(a),
|
.b(b),
|
.b(b),
|
.c(c),
|
.c(c),
|
.o(bfout),
|
.o(bfout),
|
.masko()
|
.masko()
|
);
|
);
|
|
|
FT64_multiplier #(DBW) umult1
|
FT64_multiplier #(DBW) umult1
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.clk(clk),
|
.clk(clk),
|
.ld(ld && IsMul(instr)&& (sz==word || sz==word_para)),
|
.ld(ld && IsMul(instr)&& (sz==word || sz==word_para)),
|
.abort(abort),
|
.abort(abort),
|
.sgn(IsSgn(instr)),
|
.sgn(IsSgn(instr)),
|
.sgnus(IsSgnus(instr)),
|
.sgnus(IsSgnus(instr)),
|
.a(a),
|
.a(a),
|
.b(b),
|
.b(b),
|
.o(prod),
|
.o(prod),
|
.done(mult_done),
|
.done(mult_done),
|
.idle(mult_idle)
|
.idle(mult_idle)
|
);
|
);
|
|
|
FT64_multiplier #(32) umulth0
|
FT64_multiplier #(32) umulth0
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.clk(clk),
|
.clk(clk),
|
.ld(ld && IsMul(instr) && (sz==half || sz==half_para)),
|
.ld(ld && IsMul(instr) && (sz==half || sz==half_para)),
|
.abort(abort),
|
.abort(abort),
|
.sgn(IsSgn(instr)),
|
.sgn(IsSgn(instr)),
|
.sgnus(IsSgnus(instr)),
|
.sgnus(IsSgnus(instr)),
|
.a(a[31:0]),
|
.a(a[31:0]),
|
.b(b[31:0]),
|
.b(b[31:0]),
|
.o(prod320),
|
.o(prod320),
|
.done(mult_done320),
|
.done(mult_done320),
|
.idle(mult_idle320)
|
.idle(mult_idle320)
|
);
|
);
|
|
|
FT64_multiplier #(16) umultc0
|
FT64_multiplier #(16) umultc0
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.clk(clk),
|
.clk(clk),
|
.ld(ld && IsMul(instr) && (sz==char || sz==char_para)),
|
.ld(ld && IsMul(instr) && (sz==char || sz==char_para)),
|
.abort(abort),
|
.abort(abort),
|
.sgn(IsSgn(instr)),
|
.sgn(IsSgn(instr)),
|
.sgnus(IsSgnus(instr)),
|
.sgnus(IsSgnus(instr)),
|
.a(a[15:0]),
|
.a(a[15:0]),
|
.b(b[15:0]),
|
.b(b[15:0]),
|
.o(prod160),
|
.o(prod160),
|
.done(mult_done160),
|
.done(mult_done160),
|
.idle(mult_idle160)
|
.idle(mult_idle160)
|
);
|
);
|
|
|
FT64_multiplier #(8) umultb0
|
FT64_multiplier #(8) umultb0
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.clk(clk),
|
.clk(clk),
|
.ld(ld && IsMul(instr) && (sz==byt || sz==byt_para)),
|
.ld(ld && IsMul(instr) && (sz==byt || sz==byt_para)),
|
.abort(abort),
|
.abort(abort),
|
.sgn(IsSgn(instr)),
|
.sgn(IsSgn(instr)),
|
.sgnus(IsSgnus(instr)),
|
.sgnus(IsSgnus(instr)),
|
.a(a[7:0]),
|
.a(a[7:0]),
|
.b(b[7:0]),
|
.b(b[7:0]),
|
.o(prod80),
|
.o(prod80),
|
.done(mult_done80),
|
.done(mult_done80),
|
.idle(mult_idle80)
|
.idle(mult_idle80)
|
);
|
);
|
|
|
`ifdef SIMD
|
`ifdef SIMD
|
FT64_multiplier #(32) umulth1
|
FT64_multiplier #(32) umulth1
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.clk(clk),
|
.clk(clk),
|
.ld(ld && IsMul(instr) && (sz==half || sz==half_para)),
|
.ld(ld && IsMul(instr) && (sz==half || sz==half_para)),
|
.abort(abort),
|
.abort(abort),
|
.sgn(IsSgn(instr)),
|
.sgn(IsSgn(instr)),
|
.sgnus(IsSgnus(instr)),
|
.sgnus(IsSgnus(instr)),
|
.a(a[63:32]),
|
.a(a[63:32]),
|
.b(b[63:32]),
|
.b(b[63:32]),
|
.o(prod321),
|
.o(prod321),
|
.done(mult_done321),
|
.done(mult_done321),
|
.idle(mult_idle321)
|
.idle(mult_idle321)
|
);
|
);
|
|
|
FT64_multiplier #(16) umultc1
|
FT64_multiplier #(16) umultc1
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.clk(clk),
|
.clk(clk),
|
.ld(ld && IsMul(instr) && (sz==char_para)),
|
.ld(ld && IsMul(instr) && (sz==char_para)),
|
.abort(abort),
|
.abort(abort),
|
.sgn(IsSgn(instr)),
|
.sgn(IsSgn(instr)),
|
.sgnus(IsSgnus(instr)),
|
.sgnus(IsSgnus(instr)),
|
.a(a[31:16]),
|
.a(a[31:16]),
|
.b(b[31:16]),
|
.b(b[31:16]),
|
.o(prod161),
|
.o(prod161),
|
.done(mult_done161),
|
.done(mult_done161),
|
.idle(mult_idle161)
|
.idle(mult_idle161)
|
);
|
);
|
|
|
FT64_multiplier #(16) umultc2
|
FT64_multiplier #(16) umultc2
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.clk(clk),
|
.clk(clk),
|
.ld(ld && IsMul(instr) && (sz==char_para)),
|
.ld(ld && IsMul(instr) && (sz==char_para)),
|
.abort(abort),
|
.abort(abort),
|
.sgn(IsSgn(instr)),
|
.sgn(IsSgn(instr)),
|
.sgnus(IsSgnus(instr)),
|
.sgnus(IsSgnus(instr)),
|
.a(a[47:32]),
|
.a(a[47:32]),
|
.b(b[47:32]),
|
.b(b[47:32]),
|
.o(prod162),
|
.o(prod162),
|
.done(mult_done162),
|
.done(mult_done162),
|
.idle(mult_idle162)
|
.idle(mult_idle162)
|
);
|
);
|
|
|
FT64_multiplier #(16) umultc3
|
FT64_multiplier #(16) umultc3
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.clk(clk),
|
.clk(clk),
|
.ld(ld && IsMul(instr) && (sz==char_para)),
|
.ld(ld && IsMul(instr) && (sz==char_para)),
|
.abort(abort),
|
.abort(abort),
|
.sgn(IsSgn(instr)),
|
.sgn(IsSgn(instr)),
|
.sgnus(IsSgnus(instr)),
|
.sgnus(IsSgnus(instr)),
|
.a(a[63:48]),
|
.a(a[63:48]),
|
.b(b[63:48]),
|
.b(b[63:48]),
|
.o(prod163),
|
.o(prod163),
|
.done(mult_done163),
|
.done(mult_done163),
|
.idle(mult_idle163)
|
.idle(mult_idle163)
|
);
|
);
|
|
|
FT64_multiplier #(8) umultb1
|
FT64_multiplier #(8) umultb1
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.clk(clk),
|
.clk(clk),
|
.ld(ld && IsMul(instr) && (sz==byt_para)),
|
.ld(ld && IsMul(instr) && (sz==byt_para)),
|
.abort(abort),
|
.abort(abort),
|
.sgn(IsSgn(instr)),
|
.sgn(IsSgn(instr)),
|
.sgnus(IsSgnus(instr)),
|
.sgnus(IsSgnus(instr)),
|
.a(a[15:8]),
|
.a(a[15:8]),
|
.b(b[15:8]),
|
.b(b[15:8]),
|
.o(prod81),
|
.o(prod81),
|
.done(mult_done81),
|
.done(mult_done81),
|
.idle(mult_idle81)
|
.idle(mult_idle81)
|
);
|
);
|
|
|
FT64_multiplier #(8) umultb2
|
FT64_multiplier #(8) umultb2
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.clk(clk),
|
.clk(clk),
|
.ld(ld && IsMul(instr) && (sz==byt_para)),
|
.ld(ld && IsMul(instr) && (sz==byt_para)),
|
.abort(abort),
|
.abort(abort),
|
.sgn(IsSgn(instr)),
|
.sgn(IsSgn(instr)),
|
.sgnus(IsSgnus(instr)),
|
.sgnus(IsSgnus(instr)),
|
.a(a[23:16]),
|
.a(a[23:16]),
|
.b(b[23:16]),
|
.b(b[23:16]),
|
.o(prod82),
|
.o(prod82),
|
.done(mult_done82),
|
.done(mult_done82),
|
.idle(mult_idle82)
|
.idle(mult_idle82)
|
);
|
);
|
|
|
FT64_multiplier #(8) umultb3
|
FT64_multiplier #(8) umultb3
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.clk(clk),
|
.clk(clk),
|
.ld(ld && IsMul(instr) && (sz==byt_para)),
|
.ld(ld && IsMul(instr) && (sz==byt_para)),
|
.abort(abort),
|
.abort(abort),
|
.sgn(IsSgn(instr)),
|
.sgn(IsSgn(instr)),
|
.sgnus(IsSgnus(instr)),
|
.sgnus(IsSgnus(instr)),
|
.a(a[31:24]),
|
.a(a[31:24]),
|
.b(b[31:24]),
|
.b(b[31:24]),
|
.o(prod83),
|
.o(prod83),
|
.done(mult_done83),
|
.done(mult_done83),
|
.idle(mult_idle83)
|
.idle(mult_idle83)
|
);
|
);
|
|
|
FT64_multiplier #(8) umultb4
|
FT64_multiplier #(8) umultb4
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.clk(clk),
|
.clk(clk),
|
.ld(ld && IsMul(instr) && (sz==byt_para)),
|
.ld(ld && IsMul(instr) && (sz==byt_para)),
|
.abort(abort),
|
.abort(abort),
|
.sgn(IsSgn(instr)),
|
.sgn(IsSgn(instr)),
|
.sgnus(IsSgnus(instr)),
|
.sgnus(IsSgnus(instr)),
|
.a(a[39:32]),
|
.a(a[39:32]),
|
.b(b[39:32]),
|
.b(b[39:32]),
|
.o(prod84),
|
.o(prod84),
|
.done(mult_done84),
|
.done(mult_done84),
|
.idle(mult_idle84)
|
.idle(mult_idle84)
|
);
|
);
|
|
|
FT64_multiplier #(8) umultb5
|
FT64_multiplier #(8) umultb5
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.clk(clk),
|
.clk(clk),
|
.ld(ld && IsMul(instr) && (sz==byt_para)),
|
.ld(ld && IsMul(instr) && (sz==byt_para)),
|
.abort(abort),
|
.abort(abort),
|
.sgn(IsSgn(instr)),
|
.sgn(IsSgn(instr)),
|
.sgnus(IsSgnus(instr)),
|
.sgnus(IsSgnus(instr)),
|
.a(a[47:40]),
|
.a(a[47:40]),
|
.b(b[47:40]),
|
.b(b[47:40]),
|
.o(prod85),
|
.o(prod85),
|
.done(mult_done85),
|
.done(mult_done85),
|
.idle(mult_idle85)
|
.idle(mult_idle85)
|
);
|
);
|
|
|
FT64_multiplier #(8) umultb6
|
FT64_multiplier #(8) umultb6
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.clk(clk),
|
.clk(clk),
|
.ld(ld && IsMul(instr) && (sz==byt_para)),
|
.ld(ld && IsMul(instr) && (sz==byt_para)),
|
.abort(abort),
|
.abort(abort),
|
.sgn(IsSgn(instr)),
|
.sgn(IsSgn(instr)),
|
.sgnus(IsSgnus(instr)),
|
.sgnus(IsSgnus(instr)),
|
.a(a[55:48]),
|
.a(a[55:48]),
|
.b(b[55:48]),
|
.b(b[55:48]),
|
.o(prod86),
|
.o(prod86),
|
.done(mult_done86),
|
.done(mult_done86),
|
.idle(mult_idle86)
|
.idle(mult_idle86)
|
);
|
);
|
|
|
FT64_multiplier #(8) umultb7
|
FT64_multiplier #(8) umultb7
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.clk(clk),
|
.clk(clk),
|
.ld(ld && IsMul(instr) && (sz==byt_para)),
|
.ld(ld && IsMul(instr) && (sz==byt_para)),
|
.abort(abort),
|
.abort(abort),
|
.sgn(IsSgn(instr)),
|
.sgn(IsSgn(instr)),
|
.sgnus(IsSgnus(instr)),
|
.sgnus(IsSgnus(instr)),
|
.a(a[63:56]),
|
.a(a[63:56]),
|
.b(b[63:56]),
|
.b(b[63:56]),
|
.o(prod87),
|
.o(prod87),
|
.done(mult_done87),
|
.done(mult_done87),
|
.idle(mult_idle87)
|
.idle(mult_idle87)
|
);
|
);
|
`endif
|
`endif
|
|
|
FT64_divider #(DBW) udiv1
|
FT64_divider #(DBW) udiv1
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.clk(clk),
|
.clk(clk),
|
.ld(ld && IsDivmod(instr) && (sz==word || sz==word_para)),
|
.ld(ld && IsDivmod(instr) && (sz==word || sz==word_para)),
|
.abort(abort),
|
.abort(abort),
|
.sgn(IsSgn(instr)),
|
.sgn(IsSgn(instr)),
|
.sgnus(IsSgnus(instr)),
|
.sgnus(IsSgnus(instr)),
|
.a(a),
|
.a(a),
|
.b(b),
|
.b(b),
|
.qo(divq),
|
.qo(divq),
|
.ro(rem),
|
.ro(rem),
|
.dvByZr(divByZero),
|
.dvByZr(divByZero),
|
.done(div_done),
|
.done(div_done),
|
.idle(div_idle)
|
.idle(div_idle)
|
);
|
);
|
|
|
wire [5:0] bshift = IsShiftAndOp(instr) ? ( instr[29] ? {instr[28],instr[22:18]} : b[5:0])
|
wire [5:0] bshift = IsShiftAndOp(instr) ? ( instr[29] ? {instr[28],instr[22:18]} : b[5:0])
|
: (instr[31:26]==`SHIFTR ? b[5:0] : {instr[30],instr[22:18]});
|
: (instr[31:26]==`SHIFTR ? b[5:0] : {instr[30],instr[22:18]});
|
|
|
FT64_shift ushft1
|
FT64_shift ushft1
|
(
|
(
|
.instr(instr),
|
.instr(instr),
|
.a(a),
|
.a(a),
|
.b(bshift),
|
.b(bshift),
|
.res(shfto),
|
.res(shfto),
|
.ov(aslo)
|
.ov(aslo)
|
);
|
);
|
|
|
FT64_shifth ushfthL
|
FT64_shifth ushfthL
|
(
|
(
|
.instr(instr),
|
.instr(instr),
|
.a(a[31:0]),
|
.a(a[31:0]),
|
.b(bshift),
|
.b(bshift),
|
.res(shftho[31:0]),
|
.res(shftho[31:0]),
|
.ov()
|
.ov()
|
);
|
);
|
|
|
FT64_shifth ushfthH
|
FT64_shifth ushfthH
|
(
|
(
|
.instr(instr),
|
.instr(instr),
|
.a(a[63:32]),
|
.a(a[63:32]),
|
.b(b[63:32]),
|
.b(b[63:32]),
|
.res(shftho[63:32]),
|
.res(shftho[63:32]),
|
.ov()
|
.ov()
|
);
|
);
|
|
|
FT64_shiftc ushftc0
|
FT64_shiftc ushftc0
|
(
|
(
|
.instr(instr),
|
.instr(instr),
|
.a(a[15:0]),
|
.a(a[15:0]),
|
.b(bshift),
|
.b(bshift),
|
.res(shftco[15:0]),
|
.res(shftco[15:0]),
|
.ov()
|
.ov()
|
);
|
);
|
|
|
FT64_shiftc ushftc1
|
FT64_shiftc ushftc1
|
(
|
(
|
.instr(instr),
|
.instr(instr),
|
.a(a[31:16]),
|
.a(a[31:16]),
|
.b(b[31:16]),
|
.b(b[31:16]),
|
.res(shftco[31:16]),
|
.res(shftco[31:16]),
|
.ov()
|
.ov()
|
);
|
);
|
|
|
FT64_shiftc ushftc2
|
FT64_shiftc ushftc2
|
(
|
(
|
.instr(instr),
|
.instr(instr),
|
.a(a[47:32]),
|
.a(a[47:32]),
|
.b(b[47:32]),
|
.b(b[47:32]),
|
.res(shftco[47:32]),
|
.res(shftco[47:32]),
|
.ov()
|
.ov()
|
);
|
);
|
|
|
FT64_shiftc ushftc3
|
FT64_shiftc ushftc3
|
(
|
(
|
.instr(instr),
|
.instr(instr),
|
.a(a[63:48]),
|
.a(a[63:48]),
|
.b(b[63:48]),
|
.b(b[63:48]),
|
.res(shftco[63:48]),
|
.res(shftco[63:48]),
|
.ov()
|
.ov()
|
);
|
);
|
|
|
FT64_shiftb ushftb0
|
FT64_shiftb ushftb0
|
(
|
(
|
.instr(instr),
|
.instr(instr),
|
.a(a[7:0]),
|
.a(a[7:0]),
|
.b(bshift),
|
.b(bshift),
|
.res(shftob[7:0]),
|
.res(shftob[7:0]),
|
.ov()
|
.ov()
|
);
|
);
|
|
|
FT64_shiftb ushftb1
|
FT64_shiftb ushftb1
|
(
|
(
|
.instr(instr),
|
.instr(instr),
|
.a(a[15:8]),
|
.a(a[15:8]),
|
.b(b[15:8]),
|
.b(b[15:8]),
|
.res(shftob[15:8]),
|
.res(shftob[15:8]),
|
.ov()
|
.ov()
|
);
|
);
|
|
|
FT64_shiftb ushftb2
|
FT64_shiftb ushftb2
|
(
|
(
|
.instr(instr),
|
.instr(instr),
|
.a(a[23:16]),
|
.a(a[23:16]),
|
.b(b[23:16]),
|
.b(b[23:16]),
|
.res(shftob[23:16]),
|
.res(shftob[23:16]),
|
.ov()
|
.ov()
|
);
|
);
|
|
|
FT64_shiftb ushftb3
|
FT64_shiftb ushftb3
|
(
|
(
|
.instr(instr),
|
.instr(instr),
|
.a(a[31:24]),
|
.a(a[31:24]),
|
.b(b[31:24]),
|
.b(b[31:24]),
|
.res(shftob[31:24]),
|
.res(shftob[31:24]),
|
.ov()
|
.ov()
|
);
|
);
|
|
|
FT64_shiftb ushftb4
|
FT64_shiftb ushftb4
|
(
|
(
|
.instr(instr),
|
.instr(instr),
|
.a(a[39:32]),
|
.a(a[39:32]),
|
.b(b[39:32]),
|
.b(b[39:32]),
|
.res(shftob[39:32]),
|
.res(shftob[39:32]),
|
.ov()
|
.ov()
|
);
|
);
|
|
|
FT64_shiftb ushftb5
|
FT64_shiftb ushftb5
|
(
|
(
|
.instr(instr),
|
.instr(instr),
|
.a(a[47:40]),
|
.a(a[47:40]),
|
.b(b[47:40]),
|
.b(b[47:40]),
|
.res(shftob[47:40]),
|
.res(shftob[47:40]),
|
.ov()
|
.ov()
|
);
|
);
|
|
|
FT64_shiftb ushftb6
|
FT64_shiftb ushftb6
|
(
|
(
|
.instr(instr),
|
.instr(instr),
|
.a(a[55:48]),
|
.a(a[55:48]),
|
.b(b[55:48]),
|
.b(b[55:48]),
|
.res(shftob[55:48]),
|
.res(shftob[55:48]),
|
.ov()
|
.ov()
|
);
|
);
|
|
|
FT64_shiftb ushftb7
|
FT64_shiftb ushftb7
|
(
|
(
|
.instr(instr),
|
.instr(instr),
|
.a(a[63:56]),
|
.a(a[63:56]),
|
.b(b[63:56]),
|
.b(b[63:56]),
|
.res(shftob[63:56]),
|
.res(shftob[63:56]),
|
.ov()
|
.ov()
|
);
|
);
|
|
|
cntlz64 uclz1
|
cntlz64 uclz1
|
(
|
(
|
.i(sz==2'd0 ? {56'hFFFFFFFFFFFFFF,a[7:0]} :
|
.i(sz==2'd0 ? {56'hFFFFFFFFFFFFFF,a[7:0]} :
|
sz==2'd1 ? {48'hFFFFFFFFFFFF,a[15:0]} :
|
sz==2'd1 ? {48'hFFFFFFFFFFFF,a[15:0]} :
|
sz==2'd2 ? {32'hFFFFFFFF,a[31:0]} : a),
|
sz==2'd2 ? {32'hFFFFFFFF,a[31:0]} : a),
|
.o(clzo)
|
.o(clzo)
|
);
|
);
|
|
|
cntlo64 uclo1
|
cntlo64 uclo1
|
(
|
(
|
.i(sz==2'd0 ? a[7:0] : sz==2'd1 ? a[15:0] : sz==2'd2 ? a[31:0] : a),
|
.i(sz==2'd0 ? a[7:0] : sz==2'd1 ? a[15:0] : sz==2'd2 ? a[31:0] : a),
|
.o(cloo)
|
.o(cloo)
|
);
|
);
|
|
|
cntpop64 ucpop1
|
cntpop64 ucpop1
|
(
|
(
|
.i(sz==2'd0 ? a[7:0] : sz==2'd1 ? a[15:0] : sz==2'd2 ? a[31:0] : a),
|
.i(sz==2'd0 ? a[7:0] : sz==2'd1 ? a[15:0] : sz==2'd2 ? a[31:0] : a),
|
.o(cpopo)
|
.o(cpopo)
|
);
|
);
|
|
|
wire [7:0] bcdaddo,bcdsubo;
|
wire [7:0] bcdaddo,bcdsubo;
|
wire [15:0] bcdmulo;
|
wire [15:0] bcdmulo;
|
BCDAdd ubcd1 (1'b0,a,b,bcdaddo);
|
BCDAdd ubcd1 (1'b0,a,b,bcdaddo);
|
BCDSub ubcd2 (1'b0,a,b,bcdsubo);
|
BCDSub ubcd2 (1'b0,a,b,bcdsubo);
|
BCDMul2 ubcd3 (a,b,bcdmulo);
|
BCDMul2 ubcd3 (a,b,bcdmulo);
|
|
|
wire [7:0] s8 = a[7:0] + b[7:0];
|
wire [7:0] s8 = a[7:0] + b[7:0];
|
wire [15:0] s16 = a[15:0] + b[15:0];
|
wire [15:0] s16 = a[15:0] + b[15:0];
|
wire [31:0] s32 = a[31:0] + b[31:0];
|
wire [31:0] s32 = a[31:0] + b[31:0];
|
wire [7:0] d8 = a[7:0] - b[7:0];
|
wire [7:0] d8 = a[7:0] - b[7:0];
|
wire [15:0] d16 = a[15:0] - b[15:0];
|
wire [15:0] d16 = a[15:0] - b[15:0];
|
wire [31:0] d32 = a[31:0] - b[31:0];
|
wire [31:0] d32 = a[31:0] - b[31:0];
|
wire [63:0] and64 = a & b;
|
wire [63:0] and64 = a & b;
|
wire [63:0] or64 = a | b;
|
wire [63:0] or64 = a | b;
|
wire [63:0] xor64 = a ^ b;
|
wire [63:0] xor64 = a ^ b;
|
wire [63:0] redor64 = {63'd0,|a};
|
wire [63:0] redor64 = {63'd0,|a};
|
wire [63:0] redor32 = {31'd0,|a[63:32],31'd0,|a[31:0]};
|
wire [63:0] redor32 = {31'd0,|a[63:32],31'd0,|a[31:0]};
|
wire [63:0] redor16 = {15'd0,|a[63:48],15'd0,|a[47:32],15'd0,|a[31:16],15'd0,|a[15:0]};
|
wire [63:0] redor16 = {15'd0,|a[63:48],15'd0,|a[47:32],15'd0,|a[31:16],15'd0,|a[15:0]};
|
wire [63:0] redor8 = {7'b0,|a[63:56],6'b0,|a[55:48],7'd0,|a[47:40],7'd0,|a[39:32],7'd0,
|
wire [63:0] redor8 = {7'b0,|a[63:56],6'b0,|a[55:48],7'd0,|a[47:40],7'd0,|a[39:32],7'd0,
|
|a[31:24],7'd0,|a[23:16],7'd0,|a[15:8],7'd0,|a[7:0]};
|
|a[31:24],7'd0,|a[23:16],7'd0,|a[15:8],7'd0,|a[7:0]};
|
wire [63:0] redand64 = {63'd0,&a};
|
wire [63:0] redand64 = {63'd0,&a};
|
wire [63:0] redand32 = {31'd0,&a[63:32],31'd0,&a[31:0]};
|
wire [63:0] redand32 = {31'd0,&a[63:32],31'd0,&a[31:0]};
|
wire [63:0] redand16 = {15'd0,&a[63:48],15'd0,&a[47:32],15'd0,&a[31:16],15'd0,&a[15:0]};
|
wire [63:0] redand16 = {15'd0,&a[63:48],15'd0,&a[47:32],15'd0,&a[31:16],15'd0,&a[15:0]};
|
wire [63:0] redand8 = {7'b0,&a[63:56],6'b0,&a[55:48],7'd0,&a[47:40],7'd0,&a[39:32],7'd0,
|
wire [63:0] redand8 = {7'b0,&a[63:56],6'b0,&a[55:48],7'd0,&a[47:40],7'd0,&a[39:32],7'd0,
|
&a[31:24],7'd0,&a[23:16],7'd0,&a[15:8],7'd0,&a[7:0]};
|
&a[31:24],7'd0,&a[23:16],7'd0,&a[15:8],7'd0,&a[7:0]};
|
wire [63:0] zxb10 = {54'd0,b[9:0]};
|
wire [63:0] zxb10 = {54'd0,b[9:0]};
|
wire [63:0] sxb10 = {{54{b[9]}},b[9:0]};
|
wire [63:0] sxb10 = {{54{b[9]}},b[9:0]};
|
wire [63:0] zxb26 = {38'd0,instr[47:32],instr[27:18]};
|
wire [63:0] zxb26 = {38'd0,instr[47:32],instr[27:18]};
|
wire [63:0] sxb26 = {{38{instr[47]}},instr[47:32],instr[27:18]};
|
wire [63:0] sxb26 = {{38{instr[47]}},instr[47:32],instr[27:18]};
|
reg [15:0] mask;
|
reg [15:0] mask;
|
wire [4:0] cpopom;
|
wire [4:0] cpopom;
|
wire signed [63:0] as = a;
|
wire signed [63:0] as = a;
|
wire signed [63:0] bs = b;
|
wire signed [63:0] bs = b;
|
wire signed [63:0] cs = c;
|
wire signed [63:0] cs = c;
|
|
|
always @*
|
always @*
|
for (n = 0; n < 16; n = n + 1)
|
for (n = 0; n < 16; n = n + 1)
|
if (n <= ven)
|
if (n <= ven)
|
mask[n] = 1'b1;
|
mask[n] = 1'b1;
|
else
|
else
|
mask[n] = 1'b0;
|
mask[n] = 1'b0;
|
|
|
cntpop16 ucpop2
|
cntpop16 ucpop2
|
(
|
(
|
.i(vm & mask),
|
.i(vm & mask),
|
.o(cpopom)
|
.o(cpopom)
|
);
|
);
|
|
|
wire [5:0] lsto, fsto;
|
wire [5:0] lsto, fsto;
|
ffz24 uffo1
|
ffz24 uffo1
|
(
|
(
|
.i(~{8'h00,a[15:0]}),
|
.i(~{8'h00,a[15:0]}),
|
.o(lsto)
|
.o(lsto)
|
);
|
);
|
|
|
flz24 uflo1
|
flz24 uflo1
|
(
|
(
|
.i(~{8'h00,a[15:0]}),
|
.i(~{8'h00,a[15:0]}),
|
.o(fsto)
|
.o(fsto)
|
);
|
);
|
|
|
wire [DBW-1:0] bmmo;
|
wire [DBW-1:0] bmmo;
|
FT64_BMM ubmm1
|
FT64_BMM ubmm1
|
(
|
(
|
.op(1'b0),
|
.op(1'b0),
|
.a(a),
|
.a(a),
|
.b(b),
|
.b(b),
|
.o(bmmo)
|
.o(bmmo)
|
);
|
);
|
|
|
always @*
|
always @*
|
begin
|
begin
|
case(instr[`INSTRUCTION_OP])
|
case(instr[`INSTRUCTION_OP])
|
`IVECTOR:
|
`IVECTOR:
|
if (SUP_VECTOR)
|
if (SUP_VECTOR)
|
case(instr[`INSTRUCTION_S2])
|
case(instr[`INSTRUCTION_S2])
|
`VABS: o[63:0] = a[63] ? -a : a;
|
`VABS: o[63:0] = a[63] ? -a : a;
|
`VSIGN: o[63:0] = a[63] ? 64'hFFFFFFFFFFFFFFFF : a==64'd0 ? 64'd0 : 64'd1;
|
`VSIGN: o[63:0] = a[63] ? 64'hFFFFFFFFFFFFFFFF : a==64'd0 ? 64'd0 : 64'd1;
|
`VMxx:
|
`VMxx:
|
case(instr[25:23])
|
case(instr[25:23])
|
`VMAND: o[63:0] = and64;
|
`VMAND: o[63:0] = and64;
|
`VMOR: o[63:0] = or64;
|
`VMOR: o[63:0] = or64;
|
`VMXOR: o[63:0] = xor64;
|
`VMXOR: o[63:0] = xor64;
|
`VMXNOR: o[63:0] = ~(xor64);
|
`VMXNOR: o[63:0] = ~(xor64);
|
`VMPOP: o[63:0] = {57'd0,cpopo};
|
`VMPOP: o[63:0] = {57'd0,cpopo};
|
`VMFILL: for (n = 0; n < 64; n = n + 1)
|
`VMFILL: for (n = 0; n < 64; n = n + 1)
|
o[n] = (n < a);
|
o[n] = (n < a);
|
// Change the following when VL > 16
|
// Change the following when VL > 16
|
`VMFIRST: o[63:0] = fsto==5'd31 ? 64'd64 : fsto;
|
`VMFIRST: o[63:0] = fsto==5'd31 ? 64'd64 : fsto;
|
`VMLAST: o[63:0] = lsto==5'd31 ? 64'd64 : lsto;
|
`VMLAST: o[63:0] = lsto==5'd31 ? 64'd64 : lsto;
|
endcase
|
endcase
|
`VADD,`VADDS: o[63:0] = vm[ven] ? a + b : c;
|
`VADD,`VADDS: o[63:0] = vm[ven] ? a + b : c;
|
`VSUB,`VSUBS: o[63:0] = vm[ven] ? a - b : c;
|
`VSUB,`VSUBS: o[63:0] = vm[ven] ? a - b : c;
|
`VMUL,`VMULS: o[63:0] = vm[ven] ? prod[DBW-1:0] : c;
|
`VMUL,`VMULS: o[63:0] = vm[ven] ? prod[DBW-1:0] : c;
|
`VDIV,`VDIVS: o[63:0] = BIG ? (vm[ven] ? divq : c) : 64'hCCCCCCCCCCCCCCCC;
|
`VDIV,`VDIVS: o[63:0] = BIG ? (vm[ven] ? divq : c) : 64'hCCCCCCCCCCCCCCCC;
|
`VAND,`VANDS: o[63:0] = vm[ven] ? a & b : c;
|
`VAND,`VANDS: o[63:0] = vm[ven] ? a & b : c;
|
`VOR,`VORS: o[63:0] = vm[ven] ? a | b : c;
|
`VOR,`VORS: o[63:0] = vm[ven] ? a | b : c;
|
`VXOR,`VXORS: o[63:0] = vm[ven] ? a ^ b : c;
|
`VXOR,`VXORS: o[63:0] = vm[ven] ? a ^ b : c;
|
`VCNTPOP: o[63:0] = {57'd0,cpopo};
|
`VCNTPOP: o[63:0] = {57'd0,cpopo};
|
`VSHLV: o[63:0] = a; // no masking here
|
`VSHLV: o[63:0] = a; // no masking here
|
`VSHRV: o[63:0] = a;
|
`VSHRV: o[63:0] = a;
|
`VCMPRSS: o[63:0] = a;
|
`VCMPRSS: o[63:0] = a;
|
`VCIDX: o[63:0] = a * ven;
|
`VCIDX: o[63:0] = a * ven;
|
`VSCAN: o[63:0] = a * (cpopom==0 ? 0 : cpopom-1);
|
`VSCAN: o[63:0] = a * (cpopom==0 ? 0 : cpopom-1);
|
`VSxx,`VSxxS,
|
`VSxx,`VSxxS,
|
`VSxxb,`VSxxSb:
|
`VSxxb,`VSxxSb:
|
case({instr[26],instr[20:19]})
|
case({instr[26],instr[20:19]})
|
`VSEQ: begin
|
`VSEQ: begin
|
o[63:0] = c;
|
o[63:0] = c;
|
o[ven] = vm[ven] ? a==b : c[ven];
|
o[ven] = vm[ven] ? a==b : c[ven];
|
end
|
end
|
`VSNE: begin
|
`VSNE: begin
|
o[63:0] = c;
|
o[63:0] = c;
|
o[ven] = vm[ven] ? a!=b : c[ven];
|
o[ven] = vm[ven] ? a!=b : c[ven];
|
end
|
end
|
`VSLT: begin
|
`VSLT: begin
|
o[63:0] = c;
|
o[63:0] = c;
|
o[ven] = vm[ven] ? $signed(a) < $signed(b) : c[ven];
|
o[ven] = vm[ven] ? $signed(a) < $signed(b) : c[ven];
|
end
|
end
|
`VSGE: begin
|
`VSGE: begin
|
o[63:0] = c;
|
o[63:0] = c;
|
o[ven] = vm[ven] ? $signed(a) >= $signed(b) : c[ven];
|
o[ven] = vm[ven] ? $signed(a) >= $signed(b) : c[ven];
|
end
|
end
|
`VSLE: begin
|
`VSLE: begin
|
o[63:0] = c;
|
o[63:0] = c;
|
o[ven] = vm[ven] ? $signed(a) <= $signed(b) : c[ven];
|
o[ven] = vm[ven] ? $signed(a) <= $signed(b) : c[ven];
|
end
|
end
|
`VSGT: begin
|
`VSGT: begin
|
o[63:0] = c;
|
o[63:0] = c;
|
o[ven] = vm[ven] ? $signed(a) > $signed(b) : c[ven];
|
o[ven] = vm[ven] ? $signed(a) > $signed(b) : c[ven];
|
end
|
end
|
default: o[63:0] = 64'hCCCCCCCCCCCCCCCC;
|
default: o[63:0] = 64'hCCCCCCCCCCCCCCCC;
|
endcase
|
endcase
|
`VSxxU,`VSxxSU,
|
`VSxxU,`VSxxSU,
|
`VSxxUb,`VSxxSUb:
|
`VSxxUb,`VSxxSUb:
|
case({instr[26],instr[20:19]})
|
case({instr[26],instr[20:19]})
|
`VSEQ: begin
|
`VSEQ: begin
|
o[63:0] = c;
|
o[63:0] = c;
|
o[ven] = vm[ven] ? a==b : c[ven];
|
o[ven] = vm[ven] ? a==b : c[ven];
|
end
|
end
|
`VSNE: begin
|
`VSNE: begin
|
o[63:0] = c;
|
o[63:0] = c;
|
o[ven] = vm[ven] ? a!=b : c[ven];
|
o[ven] = vm[ven] ? a!=b : c[ven];
|
end
|
end
|
`VSLT: begin
|
`VSLT: begin
|
o[63:0] = c;
|
o[63:0] = c;
|
o[ven] = vm[ven] ? a < b : c[ven];
|
o[ven] = vm[ven] ? a < b : c[ven];
|
end
|
end
|
`VSGE: begin
|
`VSGE: begin
|
o[63:0] = c;
|
o[63:0] = c;
|
o[ven] = vm[ven] ? a >= b : c[ven];
|
o[ven] = vm[ven] ? a >= b : c[ven];
|
end
|
end
|
`VSLE: begin
|
`VSLE: begin
|
o[63:0] = c;
|
o[63:0] = c;
|
o[ven] = vm[ven] ? a <= b : c[ven];
|
o[ven] = vm[ven] ? a <= b : c[ven];
|
end
|
end
|
`VSGT: begin
|
`VSGT: begin
|
o[63:0] = c;
|
o[63:0] = c;
|
o[ven] = vm[ven] ? a > b : c[ven];
|
o[ven] = vm[ven] ? a > b : c[ven];
|
end
|
end
|
default: o[63:0] = 64'hCCCCCCCCCCCCCCCC;
|
default: o[63:0] = 64'hCCCCCCCCCCCCCCCC;
|
endcase
|
endcase
|
`VBITS2V: o[63:0] = vm[ven] ? a[ven] : c;
|
`VBITS2V: o[63:0] = vm[ven] ? a[ven] : c;
|
`V2BITS: begin
|
`V2BITS: begin
|
o[63:0] = b;
|
o[63:0] = b;
|
o[ven] = vm[ven] ? a[0] : b[ven];
|
o[ven] = vm[ven] ? a[0] : b[ven];
|
end
|
end
|
`VSHL,`VSHR,`VASR: o[63:0] = BIG ? shfto : 64'hCCCCCCCCCCCCCCCC;
|
`VSHL,`VSHR,`VASR: o[63:0] = BIG ? shfto : 64'hCCCCCCCCCCCCCCCC;
|
`VXCHG: o[63:0] = vm[ven] ? b : a;
|
`VXCHG: o[63:0] = vm[ven] ? b : a;
|
default: o[63:0] = 64'hCCCCCCCCCCCCCCCC;
|
default: o[63:0] = 64'hCCCCCCCCCCCCCCCC;
|
endcase
|
endcase
|
else
|
else
|
o[63:0] <= 64'hCCCCCCCCCCCCCCCC;
|
o[63:0] <= 64'hCCCCCCCCCCCCCCCC;
|
`R2:
|
`R2:
|
if (instr[6])
|
if (instr[6])
|
case(instr[47:42])
|
case(instr[47:42])
|
`SHIFTR:
|
`SHIFTR:
|
begin
|
begin
|
case(instr[35:33])
|
case(instr[35:33])
|
`ASL,`ASR,`ROL,`ROR:
|
`ASL,`ASR,`ROL,`ROR:
|
case(instr[32:30]) // size
|
case(instr[32:30]) // size
|
3'd0: shift8 = {{56{shftob[7]}},shftob[7:0]};
|
3'd0: shift8 = {{56{shftob[7]}},shftob[7:0]};
|
3'd1: shift8 = {{48{shftob[15]}},shftco[15:0]};
|
3'd1: shift8 = {{48{shftob[15]}},shftco[15:0]};
|
3'd2: shift8 = {{32{shftho[31]}},shftho[31:0]};
|
3'd2: shift8 = {{32{shftho[31]}},shftho[31:0]};
|
3'd3,3'd7: shift8 = shfto;
|
3'd3,3'd7: shift8 = shfto;
|
3'd4: shift8 = shftob;
|
3'd4: shift8 = shftob;
|
3'd5: shift8 = shftco;
|
3'd5: shift8 = shftco;
|
3'd6: shift8 = shftho;
|
3'd6: shift8 = shftho;
|
endcase
|
endcase
|
`SHL,`SHR:
|
`SHL,`SHR:
|
case(instr[32:30]) // size
|
case(instr[32:30]) // size
|
3'd0: shift8 = {56'd0,shftob[7:0]};
|
3'd0: shift8 = {56'd0,shftob[7:0]};
|
3'd1: shift8 = {48'd0,shftco[15:0]};
|
3'd1: shift8 = {48'd0,shftco[15:0]};
|
3'd2: shift8 = {32'd0,shftho[31:0]};
|
3'd2: shift8 = {32'd0,shftho[31:0]};
|
3'd3,3'd7: shift8 = shfto;
|
3'd3,3'd7: shift8 = shfto;
|
3'd4: shift8 = shftob;
|
3'd4: shift8 = shftob;
|
3'd5: shift8 = shftco;
|
3'd5: shift8 = shftco;
|
3'd6: shift8 = shftho;
|
3'd6: shift8 = shftho;
|
endcase
|
endcase
|
default: o[63:0] = 64'hDCDCDCDCDCDCDCDC;
|
default: o[63:0] = 64'hDCDCDCDCDCDCDCDC;
|
endcase
|
endcase
|
case(instr[35:33])
|
case(instr[35:33])
|
`ASL,`ASR,`SHL,`SHR,`ROL,`ROR:
|
`ASL,`ASR,`SHL,`SHR,`ROL,`ROR:
|
o[63:0] = shift10;
|
o[63:0] = shift10;
|
default: o[63:0] = 64'hDCDCDCDCDCDCDCDC;
|
default: o[63:0] = 64'hDCDCDCDCDCDCDCDC;
|
endcase
|
endcase
|
end
|
end
|
`MIN:
|
`MIN:
|
case(instr[30:28])
|
case(instr[30:28])
|
3'd3:
|
3'd3:
|
if (as < bs && as < cs)
|
if (as < bs && as < cs)
|
o[63:0] = as;
|
o[63:0] = as;
|
else if (bs < cs)
|
else if (bs < cs)
|
o[63:0] = bs;
|
o[63:0] = bs;
|
else
|
else
|
o[63:0] = cs;
|
o[63:0] = cs;
|
default: o = 64'hDEADDEADDEADDEAD;
|
default: o = 64'hDEADDEADDEADDEAD;
|
endcase
|
endcase
|
`CMOVEZ: begin
|
`CMOVEZ: begin
|
o = (a==64'd0) ? b : c;
|
o = (a==64'd0) ? b : c;
|
end
|
end
|
`CMOVNZ: if (instr[41:39]==3'd4)
|
`CMOVNZ: if (instr[41:39]==3'd4)
|
o = (a!=64'd0) ? b : {{48{instr[38]}},instr[38:23]};
|
o = (a!=64'd0) ? b : {{48{instr[38]}},instr[38:23]};
|
else
|
else
|
o = (a!=64'd0) ? b : c;
|
o = (a!=64'd0) ? b : c;
|
default: o = 64'hDEADDEADDEADDEAD;
|
default: o = 64'hDEADDEADDEADDEAD;
|
endcase
|
endcase
|
else
|
else
|
casez(instr[`INSTRUCTION_S2])
|
casez(instr[`INSTRUCTION_S2])
|
`BCD:
|
`BCD:
|
case(instr[`INSTRUCTION_S1])
|
case(instr[`INSTRUCTION_S1])
|
`BCDADD: o[63:0] = BIG ? bcdaddo : 64'hCCCCCCCCCCCCCCCC;
|
`BCDADD: o[63:0] = BIG ? bcdaddo : 64'hCCCCCCCCCCCCCCCC;
|
`BCDSUB: o[63:0] = BIG ? bcdsubo : 64'hCCCCCCCCCCCCCCCC;
|
`BCDSUB: o[63:0] = BIG ? bcdsubo : 64'hCCCCCCCCCCCCCCCC;
|
`BCDMUL: o[63:0] = BIG ? bcdmulo : 64'hCCCCCCCCCCCCCCCC;
|
`BCDMUL: o[63:0] = BIG ? bcdmulo : 64'hCCCCCCCCCCCCCCCC;
|
default: o[63:0] = 64'hDEADDEADDEADDEAD;
|
default: o[63:0] = 64'hDEADDEADDEADDEAD;
|
endcase
|
endcase
|
`MOV: begin
|
`MOV: begin
|
o[63:0] = a;
|
o[63:0] = a;
|
end
|
end
|
`VMOV: o[63:0] = a;
|
`VMOV: o[63:0] = a;
|
`R1:
|
`R1:
|
case(instr[`INSTRUCTION_S1])
|
case(instr[`INSTRUCTION_S1])
|
`CNTLZ: o[63:0] = BIG ? {57'd0,clzo} : 64'hCCCCCCCCCCCCCCCC;
|
`CNTLZ: o[63:0] = BIG ? {57'd0,clzo} : 64'hCCCCCCCCCCCCCCCC;
|
`CNTLO: o[63:0] = BIG ? {57'd0,cloo} : 64'hCCCCCCCCCCCCCCCC;
|
`CNTLO: o[63:0] = BIG ? {57'd0,cloo} : 64'hCCCCCCCCCCCCCCCC;
|
`CNTPOP: o[63:0] = BIG ? {57'd0,cpopo} : 64'hCCCCCCCCCCCCCCCC;
|
`CNTPOP: o[63:0] = BIG ? {57'd0,cpopo} : 64'hCCCCCCCCCCCCCCCC;
|
`ABS: case(sz[1:0])
|
`ABS: case(sz[1:0])
|
2'd0: o[63:0] = BIG ? (a[7] ? -a[7:0] : a[7:0]) : 64'hCCCCCCCCCCCCCCCC;
|
2'd0: o[63:0] = BIG ? (a[7] ? -a[7:0] : a[7:0]) : 64'hCCCCCCCCCCCCCCCC;
|
2'd1: o[63:0] = BIG ? (a[15] ? -a[15:0] : a[15:0]) : 64'hCCCCCCCCCCCCCCCC;
|
2'd1: o[63:0] = BIG ? (a[15] ? -a[15:0] : a[15:0]) : 64'hCCCCCCCCCCCCCCCC;
|
2'd2: o[63:0] = BIG ? (a[31] ? -a[31:0] : a[31:0]) : 64'hCCCCCCCCCCCCCCCC;
|
2'd2: o[63:0] = BIG ? (a[31] ? -a[31:0] : a[31:0]) : 64'hCCCCCCCCCCCCCCCC;
|
2'd3: o[63:0] = BIG ? (a[63] ? -a : a) : 64'hCCCCCCCCCCCCCCCC;
|
2'd3: o[63:0] = BIG ? (a[63] ? -a : a) : 64'hCCCCCCCCCCCCCCCC;
|
endcase
|
endcase
|
`NOT: case(sz[1:0])
|
`NOT: case(sz[1:0])
|
2'd0: o = {~|a[63:56],~|a[55:48],~|a[47:40],~|a[39:32],~|a[31:24],~|a[23:16],~|a[15:8],~|a[7:0]};
|
2'd0: o = {~|a[63:56],~|a[55:48],~|a[47:40],~|a[39:32],~|a[31:24],~|a[23:16],~|a[15:8],~|a[7:0]};
|
2'd1: o = {~|a[63:48],~|a[47:32],~|a[31:16],~|a[15:0]};
|
2'd1: o = {~|a[63:48],~|a[47:32],~|a[31:16],~|a[15:0]};
|
2'd2: o = {~|a[63:32],~|a[31:0]};
|
2'd2: o = {~|a[63:32],~|a[31:0]};
|
2'd3: o = ~|a[63:0];
|
2'd3: o = ~|a[63:0];
|
endcase
|
endcase
|
`NEG:
|
`NEG:
|
case(sz[1:0])
|
case(sz[1:0])
|
2'd0: o = {-a[63:56],-a[55:48],-a[47:40],-a[39:32],-a[31:24],-a[23:16],-a[15:8],-a[7:0]};
|
2'd0: o = {-a[63:56],-a[55:48],-a[47:40],-a[39:32],-a[31:24],-a[23:16],-a[15:8],-a[7:0]};
|
2'd1: o = {-a[63:48],-a[47:32],-a[31:16],-a[15:0]};
|
2'd1: o = {-a[63:48],-a[47:32],-a[31:16],-a[15:0]};
|
2'd2: o = {-a[63:32],-a[31:0]};
|
2'd2: o = {-a[63:32],-a[31:0]};
|
2'd3: o = -a;
|
2'd3: o = -a;
|
endcase
|
endcase
|
`REDAND:
|
`REDAND:
|
case(sz[1:0])
|
case(sz[1:0])
|
2'd0: o = redand8;
|
2'd0: o = redand8;
|
2'd1: o = redand16;
|
2'd1: o = redand16;
|
2'd2: o = redand32;
|
2'd2: o = redand32;
|
2'd3: o = redand64;
|
2'd3: o = redand64;
|
endcase
|
endcase
|
`REDOR: case(sz[1:0])
|
`REDOR: case(sz[1:0])
|
2'd0: o = redor8;
|
2'd0: o = redor8;
|
2'd1: o = redor16;
|
2'd1: o = redor16;
|
2'd2: o = redor32;
|
2'd2: o = redor32;
|
2'd3: o = redor64;
|
2'd3: o = redor64;
|
endcase
|
endcase
|
`ZXH: o[63:0] = {32'd0,a[31:0]};
|
`ZXH: o[63:0] = {32'd0,a[31:0]};
|
`ZXC: o[63:0] = {48'd0,a[15:0]};
|
`ZXC: o[63:0] = {48'd0,a[15:0]};
|
`ZXB: o[63:0] = {56'd0,a[7:0]};
|
`ZXB: o[63:0] = {56'd0,a[7:0]};
|
`SXH: o[63:0] = {{32{a[31]}},a[31:0]};
|
`SXH: o[63:0] = {{32{a[31]}},a[31:0]};
|
`SXC: o[63:0] = {{48{a[15]}},a[15:0]};
|
`SXC: o[63:0] = {{48{a[15]}},a[15:0]};
|
`SXB: o[63:0] = {{56{a[7]}},a[7:0]};
|
`SXB: o[63:0] = {{56{a[7]}},a[7:0]};
|
// 5'h1C: o[63:0] = tmem[a[9:0]];
|
// 5'h1C: o[63:0] = tmem[a[9:0]];
|
default: o = 64'hDEADDEADDEADDEAD;
|
default: o = 64'hDEADDEADDEADDEAD;
|
endcase
|
endcase
|
`BMM: o[63:0] = BIG ? bmmo : 64'hCCCCCCCCCCCCCCCC;
|
`BMM: o[63:0] = BIG ? bmmo : 64'hCCCCCCCCCCCCCCCC;
|
`SHIFT31,
|
`SHIFT31,
|
`SHIFT63:
|
`SHIFT63:
|
begin
|
begin
|
if (instr[25:23]==`SHL || instr[25:23]==`ASL)
|
if (instr[25:23]==`SHL || instr[25:23]==`ASL)
|
o = shfto;
|
o = shfto;
|
else
|
else
|
o = BIG ? shfto : 64'hCCCCCCCCCCCCCCCC;
|
o = BIG ? shfto : 64'hCCCCCCCCCCCCCCCC;
|
$display("BIG=%d",BIG);
|
$display("BIG=%d",BIG);
|
if(!BIG)
|
if(!BIG)
|
$stop;
|
$stop;
|
end
|
end
|
`SHIFTR:
|
`SHIFTR:
|
begin
|
begin
|
if (instr[25:23]==`SHL || instr[25:23]==`ASL)
|
if (instr[25:23]==`SHL || instr[25:23]==`ASL)
|
o = shfto;
|
o = shfto;
|
else
|
else
|
o = BIG ? shfto : 64'hCCCCCCCCCCCCCCCC;
|
o = BIG ? shfto : 64'hCCCCCCCCCCCCCCCC;
|
$display("BIG=%d",BIG);
|
$display("BIG=%d",BIG);
|
if(!BIG)
|
if(!BIG)
|
$stop;
|
$stop;
|
end
|
end
|
`ADD:
|
`ADD:
|
`ifdef SIMD
|
`ifdef SIMD
|
case(sz)
|
case(sz)
|
3'd0,3'd4:
|
3'd0:
|
|
begin
|
|
o[7:0] = a[7:0] + b[7:0];
|
|
o[63:8] = {56{o[7]}};
|
|
end
|
|
3'd1:
|
|
begin
|
|
o[15:0] = a[15:0] + b[15:0];
|
|
o[63:16] = {48{o[15]}};
|
|
end
|
|
3'd2:
|
|
begin
|
|
o[31:0] = a[31:0] + b[31:0];
|
|
o[63:32] = {32{o[31]}};
|
|
end
|
|
3'd4:
|
begin
|
begin
|
o[7:0] = a[7:0] + b[7:0];
|
o[7:0] = a[7:0] + b[7:0];
|
o[15:8] = a[15:8] + b[15:8];
|
o[15:8] = a[15:8] + b[15:8];
|
o[23:16] = a[23:16] + b[23:16];
|
o[23:16] = a[23:16] + b[23:16];
|
o[31:24] = a[31:24] + b[31:24];
|
o[31:24] = a[31:24] + b[31:24];
|
o[39:32] = a[39:32] + b[39:32];
|
o[39:32] = a[39:32] + b[39:32];
|
o[47:40] = a[47:40] + b[47:40];
|
o[47:40] = a[47:40] + b[47:40];
|
o[55:48] = a[55:48] + b[55:48];
|
o[55:48] = a[55:48] + b[55:48];
|
o[63:56] = a[63:56] + b[63:56];
|
o[63:56] = a[63:56] + b[63:56];
|
end
|
end
|
3'd1,3'd5:
|
3'd5:
|
begin
|
begin
|
o[15:0] = a[15:0] + b[15:0];
|
o[15:0] = a[15:0] + b[15:0];
|
o[31:16] = a[31:16] + b[31:16];
|
o[31:16] = a[31:16] + b[31:16];
|
o[47:32] = a[47:32] + b[47:32];
|
o[47:32] = a[47:32] + b[47:32];
|
o[63:48] = a[63:48] + b[63:48];
|
o[63:48] = a[63:48] + b[63:48];
|
end
|
end
|
3'd2,3'd6:
|
3'd6:
|
begin
|
begin
|
o[31:0] = a[31:0] + b[31:0];
|
o[31:0] = a[31:0] + b[31:0];
|
o[63:32] = a[63:32] + b[63:32];
|
o[63:32] = a[63:32] + b[63:32];
|
end
|
end
|
default:
|
default:
|
begin
|
begin
|
o[63:0] = a + b;
|
o[63:0] = a + b;
|
end
|
end
|
endcase
|
endcase
|
`else
|
`else
|
o = a + b;
|
o = a + b;
|
`endif
|
`endif
|
// If the operation is SIMD the target register must be passed in arg T.
|
|
`SUB:
|
`SUB:
|
`ifdef SIMD
|
`ifdef SIMD
|
case(sz)
|
case(sz)
|
3'd0:
|
3'd0:
|
begin
|
begin
|
o[7:0] = a[7:0] - b[7:0];
|
o[7:0] = a[7:0] - b[7:0];
|
o[63:8] = t[63:8];
|
o[63:8] = {56{o[7]}};
|
|
end
|
|
3'd1:
|
|
begin
|
|
o[15:0] = a[15:0] - b[15:0];
|
|
o[63:16] = {48{o[15]}};
|
|
end
|
|
3'd2:
|
|
begin
|
|
o[31:0] = a[31:0] - b[31:0];
|
|
o[63:32] = {31{o[31]}};
|
end
|
end
|
3'd4:
|
3'd4:
|
begin
|
begin
|
o[7:0] = a[7:0] - b[7:0];
|
o[7:0] = a[7:0] - b[7:0];
|
o[15:8] = a[15:8] - b[15:8];
|
o[15:8] = a[15:8] - b[15:8];
|
o[23:16] = a[23:16] - b[23:16];
|
o[23:16] = a[23:16] - b[23:16];
|
o[31:24] = a[31:24] - b[31:24];
|
o[31:24] = a[31:24] - b[31:24];
|
o[39:32] = a[39:32] - b[39:32];
|
o[39:32] = a[39:32] - b[39:32];
|
o[47:40] = a[47:40] - b[47:40];
|
o[47:40] = a[47:40] - b[47:40];
|
o[55:48] = a[55:48] - b[55:48];
|
o[55:48] = a[55:48] - b[55:48];
|
o[63:56] = a[63:56] - b[63:56];
|
o[63:56] = a[63:56] - b[63:56];
|
end
|
end
|
3'd1,3'd5:
|
3'd5:
|
begin
|
begin
|
o[15:0] = a[15:0] - b[15:0];
|
o[15:0] = a[15:0] - b[15:0];
|
o[31:16] = a[31:16] - b[31:16];
|
o[31:16] = a[31:16] - b[31:16];
|
o[47:32] = a[47:32] - b[47:32];
|
o[47:32] = a[47:32] - b[47:32];
|
o[63:48] = a[63:48] - b[63:48];
|
o[63:48] = a[63:48] - b[63:48];
|
end
|
end
|
3'd2,3'd6:
|
3'd6:
|
begin
|
begin
|
o[31:0] = a[31:0] - b[31:0];
|
o[31:0] = a[31:0] - b[31:0];
|
o[63:32] = a[63:32] - b[63:32];
|
o[63:32] = a[63:32] - b[63:32];
|
end
|
end
|
default:
|
default:
|
begin
|
begin
|
o[63:0] = a - b;
|
o = a - b;
|
end
|
end
|
endcase
|
endcase
|
`else
|
`else
|
o = a - b;
|
o = a - b;
|
`endif
|
`endif
|
`SEQ: tskSeq(instr,instr[25:23],a,b,o);
|
`SEQ: tskSeq(instr,instr[25:23],a,b,o);
|
`SLT: tskSlt(instr,instr[25:23],a,b,o);
|
`SLT: tskSlt(instr,instr[25:23],a,b,o);
|
`SLTU: tskSltu(instr,instr[25:23],a,b,o);
|
`SLTU: tskSltu(instr,instr[25:23],a,b,o);
|
`SLE: tskSle(instr,instr[25:23],a,b,o);
|
`SLE: tskSle(instr,instr[25:23],a,b,o);
|
`SLEU: tskSleu(instr,instr[25:23],a,b,o);
|
`SLEU: tskSleu(instr,instr[25:23],a,b,o);
|
`AND: o = and64;
|
`AND: o = and64;
|
`OR: o = or64;
|
`OR: o = or64;
|
`XOR: o = xor64;
|
`XOR: o = xor64;
|
`NAND: o = ~and64;
|
`NAND: o = ~and64;
|
`NOR: o = ~or64;
|
`NOR: o = ~or64;
|
`XNOR: o = ~xor64;
|
`XNOR: o = ~xor64;
|
`SEI: o = a | instr[21:16];
|
`SEI: o = a | instr[21:16];
|
`RTI: o = a | instr[21:16];
|
`RTI: o = a | instr[21:16];
|
`MUX: for (n = 0; n < 64; n = n + 1)
|
`MUX: for (n = 0; n < 64; n = n + 1)
|
o[n] <= a[n] ? b[n] : c[n];
|
o[n] <= a[n] ? b[n] : c[n];
|
`MULU,`MULSU,`MUL:
|
`MULU,`MULSU,`MUL:
|
case(sz)
|
case(sz)
|
byt_para: o[63:0] = {prod87[7:0],prod86[7:0],prod85[7:0],prod84[7:0],prod83[7:0],prod82[7:0],prod81[7:0],prod80[7:0]};
|
byt_para: o[63:0] = {prod87[7:0],prod86[7:0],prod85[7:0],prod84[7:0],prod83[7:0],prod82[7:0],prod81[7:0],prod80[7:0]};
|
char_para: o[63:0] = {prod163[15:0],prod162[15:0],prod161[15:0],prod160[15:0]};
|
char_para: o[63:0] = {prod163[15:0],prod162[15:0],prod161[15:0],prod160[15:0]};
|
half_para: o[63:0] = {prod321[31:0],prod320[31:0]};
|
half_para: o[63:0] = {prod321[31:0],prod320[31:0]};
|
default: o[63:0] = prod[DBW-1:0];
|
default: o[63:0] = prod[DBW-1:0];
|
endcase
|
endcase
|
`FXMUL:
|
`FXMUL:
|
case(sz)
|
case(sz)
|
half_para: o = {prod321[47:16] + prod321[15],prod320[47:16] + prod320[15]};
|
half_para: o = {prod321[47:16] + prod321[15],prod320[47:16] + prod320[15]};
|
default: o = prod[95:32] + prod[31];
|
default: o = prod[95:32] + prod[31];
|
endcase
|
endcase
|
`MULF: o = a[23:0] * b[15:0];
|
`MULF: o = a[23:0] * b[15:0];
|
`DIVU: o[63:0] = BIG ? divq : 64'hCCCCCCCCCCCCCCCC;
|
`DIVU: o[63:0] = BIG ? divq : 64'hCCCCCCCCCCCCCCCC;
|
`DIVSU: o[63:0] = BIG ? divq : 64'hCCCCCCCCCCCCCCCC;
|
`DIVSU: o[63:0] = BIG ? divq : 64'hCCCCCCCCCCCCCCCC;
|
`DIV: o[63:0] = BIG ? divq : 64'hCCCCCCCCCCCCCCCC;
|
`DIV: o[63:0] = BIG ? divq : 64'hCCCCCCCCCCCCCCCC;
|
`MODU: o[63:0] = BIG ? rem : 64'hCCCCCCCCCCCCCCCC;
|
`MODU: o[63:0] = BIG ? rem : 64'hCCCCCCCCCCCCCCCC;
|
`MODSU: o[63:0] = BIG ? rem : 64'hCCCCCCCCCCCCCCCC;
|
`MODSU: o[63:0] = BIG ? rem : 64'hCCCCCCCCCCCCCCCC;
|
`MOD: o[63:0] = BIG ? rem : 64'hCCCCCCCCCCCCCCCC;
|
`MOD: o[63:0] = BIG ? rem : 64'hCCCCCCCCCCCCCCCC;
|
`LEAX:
|
`LEAX:
|
begin
|
begin
|
o[63:0] = BIG ? a + (b << instr[22:21]) : 64'hCCCCCCCCEEEEEEEE;
|
o[63:0] = BIG ? a + (b << instr[22:21]) : 64'hCCCCCCCCEEEEEEEE;
|
//o[63:44] = PTR;
|
//o[63:44] = PTR;
|
end
|
end
|
`MIN:
|
`MIN:
|
`ifdef SIMD
|
`ifdef SIMD
|
case(sz)
|
case(sz)
|
3'd0:
|
3'd0: o = BIG ? ($signed(a[7:0]) < $signed(b[7:0]) ? {{56{a[7]}},a[7:0]} : {{56{b[7]}},b[7:0]}) : 64'hCCCCCCCCCCCCCCCC;
|
begin
|
3'd1: o = BIG ? ($signed(a[15:0]) < $signed(b[15:0]) ? {{48{a[15]}},a[15:0]} : {{48{b[15]}},b[15:0]}) : 64'hCCCCCCCCCCCCCCCC;
|
o[7:0] = BIG ? ($signed(a[7:0]) < $signed(b[7:0]) ? a[7:0] : b[7:0]) : 8'hCC;
|
3'd2: o = BIG ? ($signed(a[31:0]) < $signed(b[31:0]) ? {{32{a[31]}},a[31:0]} : {{32{b[31]}},b[31:0]}) : 64'hCCCCCCCCCCCCCCCC;
|
o[63:8] = BIG ? t[63:8] : 56'hCCCCCCCCCCCCCC;
|
3'd3: o = BIG ? ($signed(a) < $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
|
end
|
|
3'd1:
|
|
begin
|
|
o[15:0] = BIG ? ($signed(a[15:0]) < $signed(b[15:0]) ? a[15:0] : b[15:0]) : 16'hCCCC;
|
|
o[63:16] = BIG ? t[63:16] : 48'hCCCCCCCCCCCC;
|
|
end
|
|
3'd2:
|
|
begin
|
|
o[31:0] = BIG ? ($signed(a[31:0]) < $signed(b[31:0]) ? a[31:0] : b[31:0]) : 32'hCCCCCCCC;
|
|
o[63:32] = BIG ? t[63:32] : 32'hCCCCCCCC;
|
|
end
|
|
3'd3:
|
|
begin
|
|
o = BIG ? ($signed(a) < $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
|
|
end
|
|
3'd4:
|
3'd4:
|
begin
|
begin
|
o[7:0] = BIG ? ($signed(a[7:0]) < $signed(b[7:0]) ? a[7:0] : b[7:0]) : 8'hCC;
|
o[7:0] = BIG ? ($signed(a[7:0]) < $signed(b[7:0]) ? a[7:0] : b[7:0]) : 8'hCC;
|
o[15:8] = BIG ? ($signed(a[15:8]) < $signed(b[15:8]) ? a[15:8] : b[15:8]) : 64'hCCCCCCCCCCCCCCCC;
|
o[15:8] = BIG ? ($signed(a[15:8]) < $signed(b[15:8]) ? a[15:8] : b[15:8]) : 64'hCCCCCCCCCCCCCCCC;
|
o[23:16] = BIG ? ($signed(a[23:16]) < $signed(b[23:16]) ? a[23:16] : b[23:16]) : 64'hCCCCCCCCCCCCCCCC;
|
o[23:16] = BIG ? ($signed(a[23:16]) < $signed(b[23:16]) ? a[23:16] : b[23:16]) : 64'hCCCCCCCCCCCCCCCC;
|
o[31:24] = BIG ? ($signed(a[31:24]) < $signed(b[31:24]) ? a[31:24] : b[31:24]) : 64'hCCCCCCCCCCCCCCCC;
|
o[31:24] = BIG ? ($signed(a[31:24]) < $signed(b[31:24]) ? a[31:24] : b[31:24]) : 64'hCCCCCCCCCCCCCCCC;
|
o[39:32] = BIG ? ($signed(a[39:32]) < $signed(b[39:32]) ? a[39:32] : b[39:32]) : 64'hCCCCCCCCCCCCCCCC;
|
o[39:32] = BIG ? ($signed(a[39:32]) < $signed(b[39:32]) ? a[39:32] : b[39:32]) : 64'hCCCCCCCCCCCCCCCC;
|
o[47:40] = BIG ? ($signed(a[47:40]) < $signed(b[47:40]) ? a[47:40] : b[47:40]) : 64'hCCCCCCCCCCCCCCCC;
|
o[47:40] = BIG ? ($signed(a[47:40]) < $signed(b[47:40]) ? a[47:40] : b[47:40]) : 64'hCCCCCCCCCCCCCCCC;
|
o[55:48] = BIG ? ($signed(a[55:48]) < $signed(b[55:48]) ? a[55:48] : b[55:48]) : 64'hCCCCCCCCCCCCCCCC;
|
o[55:48] = BIG ? ($signed(a[55:48]) < $signed(b[55:48]) ? a[55:48] : b[55:48]) : 64'hCCCCCCCCCCCCCCCC;
|
o[63:56] = BIG ? ($signed(a[63:56]) < $signed(b[63:56]) ? a[63:56] : b[63:56]) : 64'hCCCCCCCCCCCCCCCC;
|
o[63:56] = BIG ? ($signed(a[63:56]) < $signed(b[63:56]) ? a[63:56] : b[63:56]) : 64'hCCCCCCCCCCCCCCCC;
|
end
|
end
|
3'd5:
|
3'd5:
|
begin
|
begin
|
o[15:0] = BIG ? ($signed(a[15:0]) < $signed(b[15:0]) ? a[15:0] : b[15:0]) : 64'hCCCCCCCCCCCCCCCC;
|
o[15:0] = BIG ? ($signed(a[15:0]) < $signed(b[15:0]) ? a[15:0] : b[15:0]) : 64'hCCCCCCCCCCCCCCCC;
|
o[32:16] = BIG ? ($signed(a[32:16]) < $signed(b[32:16]) ? a[32:16] : b[32:16]) : 64'hCCCCCCCCCCCCCCCC;
|
o[32:16] = BIG ? ($signed(a[32:16]) < $signed(b[32:16]) ? a[32:16] : b[32:16]) : 64'hCCCCCCCCCCCCCCCC;
|
o[47:32] = BIG ? ($signed(a[47:32]) < $signed(b[47:32]) ? a[47:32] : b[47:32]) : 64'hCCCCCCCCCCCCCCCC;
|
o[47:32] = BIG ? ($signed(a[47:32]) < $signed(b[47:32]) ? a[47:32] : b[47:32]) : 64'hCCCCCCCCCCCCCCCC;
|
o[63:48] = BIG ? ($signed(a[63:48]) < $signed(b[63:48]) ? a[63:48] : b[63:48]) : 64'hCCCCCCCCCCCCCCCC;
|
o[63:48] = BIG ? ($signed(a[63:48]) < $signed(b[63:48]) ? a[63:48] : b[63:48]) : 64'hCCCCCCCCCCCCCCCC;
|
end
|
end
|
3'd6:
|
3'd6:
|
begin
|
begin
|
o[31:0] = BIG ? ($signed(a[31:0]) < $signed(b[31:0]) ? a[31:0] : b[31:0]) : 64'hCCCCCCCCCCCCCCCC;
|
o[31:0] = BIG ? ($signed(a[31:0]) < $signed(b[31:0]) ? a[31:0] : b[31:0]) : 64'hCCCCCCCCCCCCCCCC;
|
o[63:32] = BIG ? ($signed(a[63:32]) < $signed(b[63:32]) ? a[63:32] : b[63:32]) : 64'hCCCCCCCCCCCCCCCC;
|
o[63:32] = BIG ? ($signed(a[63:32]) < $signed(b[63:32]) ? a[63:32] : b[63:32]) : 64'hCCCCCCCCCCCCCCCC;
|
end
|
end
|
3'd7:
|
3'd7:
|
begin
|
begin
|
o = BIG ? ($signed(a) < $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
|
o = BIG ? ($signed(a) < $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
|
end
|
end
|
endcase
|
endcase
|
`else
|
`else
|
o = BIG ? ($signed(a) < $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
|
o = BIG ? ($signed(a) < $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
|
`endif
|
`endif
|
`MAX:
|
`MAX:
|
`ifdef SIMD
|
`ifdef SIMD
|
case(sz)
|
case(sz)
|
3'd0,3'd4:
|
3'd0: o = BIG ? ($signed(a[7:0]) > $signed(b[7:0]) ? {{56{a[7]}},a[7:0]} : {{56{b[7]}},b[7:0]}) : 64'hCCCCCCCCCCCCCCCC;
|
|
3'd1: o = BIG ? ($signed(a[15:0]) > $signed(b[15:0]) ? {{48{a[15]}},a[15:0]} : {{48{b[15]}},b[15:0]}) : 64'hCCCCCCCCCCCCCCCC;
|
|
3'd2: o = BIG ? ($signed(a[31:0]) > $signed(b[31:0]) ? {{32{a[31]}},a[31:0]} : {{32{b[31]}},b[31:0]}) : 64'hCCCCCCCCCCCCCCCC;
|
|
3'd3: o = BIG ? ($signed(a) > $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
|
|
3'd4:
|
begin
|
begin
|
o[7:0] = BIG ? ($signed(a[7:0]) > $signed(b[7:0]) ? a[7:0] : b[7:0]) : 64'hCCCCCCCCCCCCCCCC;
|
o[7:0] = BIG ? ($signed(a[7:0]) > $signed(b[7:0]) ? a[7:0] : b[7:0]) : 64'hCCCCCCCCCCCCCCCC;
|
o[15:8] = BIG ? ($signed(a[15:8]) > $signed(b[15:8]) ? a[15:8] : b[15:8]) : 64'hCCCCCCCCCCCCCCCC;
|
o[15:8] = BIG ? ($signed(a[15:8]) > $signed(b[15:8]) ? a[15:8] : b[15:8]) : 64'hCCCCCCCCCCCCCCCC;
|
o[23:16] = BIG ? ($signed(a[23:16]) > $signed(b[23:16]) ? a[23:16] : b[23:16]) : 64'hCCCCCCCCCCCCCCCC;
|
o[23:16] = BIG ? ($signed(a[23:16]) > $signed(b[23:16]) ? a[23:16] : b[23:16]) : 64'hCCCCCCCCCCCCCCCC;
|
o[31:24] = BIG ? ($signed(a[31:24]) > $signed(b[31:24]) ? a[31:24] : b[31:24]) : 64'hCCCCCCCCCCCCCCCC;
|
o[31:24] = BIG ? ($signed(a[31:24]) > $signed(b[31:24]) ? a[31:24] : b[31:24]) : 64'hCCCCCCCCCCCCCCCC;
|
o[39:32] = BIG ? ($signed(a[39:32]) > $signed(b[39:32]) ? a[39:32] : b[39:32]) : 64'hCCCCCCCCCCCCCCCC;
|
o[39:32] = BIG ? ($signed(a[39:32]) > $signed(b[39:32]) ? a[39:32] : b[39:32]) : 64'hCCCCCCCCCCCCCCCC;
|
o[47:40] = BIG ? ($signed(a[47:40]) > $signed(b[47:40]) ? a[47:40] : b[47:40]) : 64'hCCCCCCCCCCCCCCCC;
|
o[47:40] = BIG ? ($signed(a[47:40]) > $signed(b[47:40]) ? a[47:40] : b[47:40]) : 64'hCCCCCCCCCCCCCCCC;
|
o[55:48] = BIG ? ($signed(a[55:48]) > $signed(b[55:48]) ? a[55:48] : b[55:48]) : 64'hCCCCCCCCCCCCCCCC;
|
o[55:48] = BIG ? ($signed(a[55:48]) > $signed(b[55:48]) ? a[55:48] : b[55:48]) : 64'hCCCCCCCCCCCCCCCC;
|
o[63:56] = BIG ? ($signed(a[63:56]) > $signed(b[63:56]) ? a[63:56] : b[63:56]) : 64'hCCCCCCCCCCCCCCCC;
|
o[63:56] = BIG ? ($signed(a[63:56]) > $signed(b[63:56]) ? a[63:56] : b[63:56]) : 64'hCCCCCCCCCCCCCCCC;
|
end
|
end
|
3'd1,3'd5:
|
3'd5:
|
begin
|
begin
|
o[15:0] = BIG ? ($signed(a[15:0]) > $signed(b[15:0]) ? a[15:0] : b[15:0]) : 64'hCCCCCCCCCCCCCCCC;
|
o[15:0] = BIG ? ($signed(a[15:0]) > $signed(b[15:0]) ? a[15:0] : b[15:0]) : 64'hCCCCCCCCCCCCCCCC;
|
o[32:16] = BIG ? ($signed(a[32:16]) > $signed(b[32:16]) ? a[32:16] : b[32:16]) : 64'hCCCCCCCCCCCCCCCC;
|
o[32:16] = BIG ? ($signed(a[32:16]) > $signed(b[32:16]) ? a[32:16] : b[32:16]) : 64'hCCCCCCCCCCCCCCCC;
|
o[47:32] = BIG ? ($signed(a[47:32]) > $signed(b[47:32]) ? a[47:32] : b[47:32]) : 64'hCCCCCCCCCCCCCCCC;
|
o[47:32] = BIG ? ($signed(a[47:32]) > $signed(b[47:32]) ? a[47:32] : b[47:32]) : 64'hCCCCCCCCCCCCCCCC;
|
o[63:48] = BIG ? ($signed(a[63:48]) > $signed(b[63:48]) ? a[63:48] : b[63:48]) : 64'hCCCCCCCCCCCCCCCC;
|
o[63:48] = BIG ? ($signed(a[63:48]) > $signed(b[63:48]) ? a[63:48] : b[63:48]) : 64'hCCCCCCCCCCCCCCCC;
|
end
|
end
|
3'd2,3'd6:
|
3'd6:
|
begin
|
begin
|
o[31:0] = BIG ? ($signed(a[31:0]) > $signed(b[31:0]) ? a[31:0] : b[31:0]) : 64'hCCCCCCCCCCCCCCCC;
|
o[31:0] = BIG ? ($signed(a[31:0]) > $signed(b[31:0]) ? a[31:0] : b[31:0]) : 64'hCCCCCCCCCCCCCCCC;
|
o[63:32] = BIG ? ($signed(a[63:32]) > $signed(b[63:32]) ? a[63:32] : b[63:32]) : 64'hCCCCCCCCCCCCCCCC;
|
o[63:32] = BIG ? ($signed(a[63:32]) > $signed(b[63:32]) ? a[63:32] : b[63:32]) : 64'hCCCCCCCCCCCCCCCC;
|
end
|
end
|
3'd3,3'd7:
|
3'd7:
|
begin
|
begin
|
o[63:0] = BIG ? ($signed(a) > $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
|
o[63:0] = BIG ? ($signed(a) > $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
|
end
|
end
|
endcase
|
endcase
|
`else
|
`else
|
o[63:0] = BIG ? ($signed(a) > $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
|
o[63:0] = BIG ? ($signed(a) > $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
|
`endif
|
`endif
|
`MAJ: o = (a & b) | (a & c) | (b & c);
|
`MAJ: o = (a & b) | (a & c) | (b & c);
|
`CHK: o[63:0] = (a >= b && a < c);
|
`CHK: o[63:0] = (a >= b && a < c);
|
/*
|
/*
|
`RTOP: case(c[5:0])
|
`RTOP: case(c[5:0])
|
`RTADD: o = a + b;
|
`RTADD: o = a + b;
|
`RTSUB: o = a - b;
|
`RTSUB: o = a - b;
|
`RTAND: o = and64;
|
`RTAND: o = and64;
|
`RTOR: o = or64;
|
`RTOR: o = or64;
|
`RTXOR: o = xor64;
|
`RTXOR: o = xor64;
|
`RTNAND: o = ~and64;
|
`RTNAND: o = ~and64;
|
`RTNOR: o = ~or64;
|
`RTNOR: o = ~or64;
|
`RTXNOR: o = ~xor64;
|
`RTXNOR: o = ~xor64;
|
`RTSLT: o = as < bs;
|
`RTSLT: o = as < bs;
|
`RTSGE: o = as >= bs;
|
`RTSGE: o = as >= bs;
|
`RTSLE: o = as <= bs;
|
`RTSLE: o = as <= bs;
|
`RTSGT: o = as > bs;
|
`RTSGT: o = as > bs;
|
`RTSEQ: o = as==bs;
|
`RTSEQ: o = as==bs;
|
`RTSNE: o = as!=bs;
|
`RTSNE: o = as!=bs;
|
endcase
|
endcase
|
*/
|
*/
|
`TLB: o = BIG ? tlbo : 64'hDEADDEADDEADDEAD;
|
|
default: o[63:0] = 64'hDEADDEADDEADDEAD;
|
default: o[63:0] = 64'hDEADDEADDEADDEAD;
|
endcase
|
endcase
|
`MEMNDX:
|
`MEMNDX:
|
if (instr[7:6]==2'b10) begin
|
if (instr[7:6]==2'b10) begin
|
if (instr[31])
|
if (instr[31])
|
case({instr[31:28],instr[17:16]})
|
case({instr[31:28],instr[17:16]})
|
`PUSH:
|
`PUSH:
|
begin
|
begin
|
usa = a - 4'd8;
|
usa = a - 4'd8;
|
o = {pb[50:0],13'd0} + usa;
|
o = {pb[50:0],13'd0} + usa;
|
end
|
end
|
default: o = 64'hDEADDEADDEADDEAD;
|
default: o = 64'hDEADDEADDEADDEAD;
|
endcase
|
endcase
|
else
|
else
|
o = 64'hDEADDEADDEADDEAD;
|
o = 64'hDEADDEADDEADDEAD;
|
end
|
end
|
else if (instr[7:6]==2'b00) begin
|
else if (instr[7:6]==2'b00) begin
|
if (!instr[31])
|
if (!instr[31])
|
case({instr[31:28],instr[22:21]})
|
case({instr[31:28],instr[22:21]})
|
`CACHEX,`LVX,
|
`CACHEX,`LVX,
|
`LBX,`LBUX,`LCX,`LCUX,
|
`LBX,`LBUX,`LCX,`LCUX,
|
`LVBX,`LVBUX,`LVCX,`LVCUX,`LVHX,`LVHUX,`LVWX,
|
`LVBX,`LVBUX,`LVCX,`LVCUX,`LVHX,`LVHUX,`LVWX,
|
`LHX,`LHUX,`LWX,`LWRX:
|
`LHX,`LHUX,`LWX,`LWRX:
|
if (BIG) begin
|
if (BIG) begin
|
usa = a + (c << instr[19:18]);
|
usa = a + (c << instr[19:18]);
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
end
|
end
|
else
|
else
|
o = 64'hCCCCCCCCEEEEEEEE;
|
o = 64'hCCCCCCCCEEEEEEEE;
|
`LVX,`SVX:
|
`LVX,`SVX:
|
if (BIG) begin
|
if (BIG) begin
|
usa = a + (c << 2'd3);
|
usa = a + (c << 2'd3);
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
end
|
end
|
else
|
else
|
o = 64'hCCCCCCCCCCCCCCCC;
|
o = 64'hCCCCCCCCCCCCCCCC;
|
`LVWS,`SVWS:
|
`LVWS,`SVWS:
|
if (BIG) begin
|
if (BIG) begin
|
usa = a + ({c * ven,3'b000});
|
usa = a + ({c * ven,3'b000});
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
end
|
end
|
else
|
else
|
o = 64'hCCCCCCCCCCCCCCCC;
|
o = 64'hCCCCCCCCCCCCCCCC;
|
default: o = 64'hDEADDEADDEADDEAD;
|
default: o = 64'hDEADDEADDEADDEAD;
|
endcase
|
endcase
|
else
|
else
|
case({instr[31:28],instr[17:16]})
|
case({instr[31:28],instr[17:16]})
|
`PUSH:
|
`PUSH:
|
begin
|
begin
|
usa = a - 4'd8;
|
usa = a - 4'd8;
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
end
|
end
|
`SBX,`SCX,`SHX,`SWX,`SWCX:
|
`SBX,`SCX,`SHX,`SWX,`SWCX:
|
if (BIG) begin
|
if (BIG) begin
|
usa = a + (c << instr[14:13]);
|
usa = a + (c << instr[14:13]);
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
end
|
end
|
else
|
else
|
o = 64'hCCCCCCCCEEEEEEEE;
|
o = 64'hCCCCCCCCEEEEEEEE;
|
`SVX: if (BIG) begin
|
`SVX: if (BIG) begin
|
usa = a + (c << 2'd3);
|
usa = a + (c << 2'd3);
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
end
|
end
|
else
|
else
|
o = 64'hCCCCCCCCCCCCCCCC;
|
o = 64'hCCCCCCCCCCCCCCCC;
|
`SVWS:
|
`SVWS:
|
if (BIG) begin
|
if (BIG) begin
|
usa = a + ({c * ven,3'b000});
|
usa = a + ({c * ven,3'b000});
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
end
|
end
|
else
|
else
|
o = 64'hCCCCCCCCCCCCCCCC;
|
o = 64'hCCCCCCCCCCCCCCCC;
|
default: o = 64'hDEADDEADDEADDEAD;
|
default: o = 64'hDEADDEADDEADDEAD;
|
endcase
|
endcase
|
end
|
end
|
else
|
else
|
o[63:0] = 64'hDEADDEADDEADDEAD;
|
o[63:0] = 64'hDEADDEADDEADDEAD;
|
`AUIPC:
|
`AUIPC:
|
begin
|
begin
|
if (instr[7:6]==2'b01)
|
if (instr[7:6]==2'b01)
|
o[63:0] = pc + {instr[47:18],instr[12:8],30'd0};
|
o[63:0] = pc + {instr[47:18],instr[12:8],30'd0};
|
else
|
else
|
o[63:0] = pc + {{15{instr[31]}},instr[31:18],instr[12:8],30'd0};
|
o[63:0] = pc + {{15{instr[31]}},instr[31:18],instr[12:8],30'd0};
|
o[29:0] = 30'd0;
|
o[29:0] = 30'd0;
|
// o[63:44] = PTR;
|
// o[63:44] = PTR;
|
end
|
end
|
`LUI:
|
`LUI:
|
begin
|
begin
|
if (instr[7:6]==2'b01)
|
if (instr[7:6]==2'b01)
|
o = {instr[47:18],instr[12:8],30'd0};
|
o = {instr[47:18],instr[12:8],30'd0};
|
else
|
else
|
o = {{15{instr[31]}},instr[31:18],instr[12:8],30'd0};
|
o = {{15{instr[31]}},instr[31:18],instr[12:8],30'd0};
|
end
|
end
|
`ADDI: o = a + b;
|
`ADDI: o = a + b;
|
`SEQI: o = a == b;
|
`SEQI: o = a == b;
|
`SLTI: o = $signed(a) < $signed(b);
|
`SLTI: o = $signed(a) < $signed(b);
|
`SLTUI: o = a < b;
|
`SLTUI: o = a < b;
|
`SGTI: o = $signed(a) > $signed(b);
|
`SGTI: o = $signed(a) > $signed(b);
|
`SGTUI: o = a > b;
|
`SGTUI: o = a > b;
|
`ANDI: o = a & andb;
|
`ANDI: o = a & andb;
|
`ORI: o = a | orb;
|
`ORI: o = a | orb;
|
`XORI: o = a ^ orb;
|
`XORI: o = a ^ orb;
|
`XNORI: o = ~(a ^ orb);
|
`XNORI: o = ~(a ^ orb);
|
`MULUI: o = prod[DBW-1:0];
|
`MULUI: o = prod[DBW-1:0];
|
`MULI: o = prod[DBW-1:0];
|
`MULI: o = prod[DBW-1:0];
|
`MULFI: o = a[23:0] * b[15:0];
|
`MULFI: o = a[23:0] * b[15:0];
|
`DIVUI: o = BIG ? divq : 64'hCCCCCCCCCCCCCCCC;
|
`DIVUI: o = BIG ? divq : 64'hCCCCCCCCCCCCCCCC;
|
`DIVI: o = BIG ? divq : 64'hCCCCCCCCCCCCCCCC;
|
`DIVI: o = BIG ? divq : 64'hCCCCCCCCCCCCCCCC;
|
`MODI: o = BIG ? rem : 64'hCCCCCCCCCCCCCCCC;
|
`MODI: o = BIG ? rem : 64'hCCCCCCCCCCCCCCCC;
|
`LB,`LBU,`SB:
|
`LB,`LBU,`SB:
|
begin
|
begin
|
usa = a + b;
|
usa = a + b;
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
end
|
end
|
`Lx,`LxU,`Sx,`LVx,`LVxU:
|
`Lx,`LxU,`Sx,`LVx,`LVxU:
|
casez(b[2:0])
|
casez(b[2:0])
|
3'b100:
|
3'b100:
|
begin
|
begin
|
usa = a + {b[63:3],3'b0}; // LW / SW
|
usa = a + {b[63:3],3'b0}; // LW / SW
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
end
|
end
|
3'b?10:
|
3'b?10:
|
begin
|
begin
|
usa = a + {b[63:2],2'b0}; // LH / LHU / SH
|
usa = a + {b[63:2],2'b0}; // LH / LHU / SH
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
end
|
end
|
default:
|
default:
|
begin
|
begin
|
usa = a + {b[63:1],1'b0}; // LC / LCU / SC
|
usa = a + {b[63:1],1'b0}; // LC / LCU / SC
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
end
|
end
|
endcase
|
endcase
|
`PUSHC:
|
`PUSHC:
|
begin
|
begin
|
usa = a - 4'd8;
|
usa = a - 4'd8;
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
end
|
end
|
`LWR,`SWC,`CAS,`CACHE:
|
`LWR,`SWC,`CAS,`CACHE:
|
begin
|
begin
|
usa = a + b;
|
usa = a + b;
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
end
|
end
|
`LV,`SV:
|
`LV,`SV:
|
begin
|
begin
|
usa = a + b + {ven,3'b0};
|
usa = a + b + {ven,3'b0};
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
o = {pb[50:0],BASE_SHIFT} + usa;
|
end
|
end
|
`CSRRW:
|
`CSRRW:
|
case(instr[27:18])
|
case(instr[27:18])
|
10'h044: o = BIG ? (csr | {39'd0,thrd,24'h0}) : 64'hDDDDDDDDDDDDDDDD;
|
10'h044: o = BIG ? (csr | {39'd0,thrd,24'h0}) : 64'hDDDDDDDDDDDDDDDD;
|
default: o = BIG ? csr : 64'hDDDDDDDDDDDDDDDD;
|
default: o = BIG ? csr : 64'hDDDDDDDDDDDDDDDD;
|
endcase
|
endcase
|
`BITFIELD: o = BIG ? bfout : 64'hCCCCCCCCCCCCCCCC;
|
`BITFIELD: o = BIG ? bfout : 64'hCCCCCCCCCCCCCCCC;
|
default: o = 64'hDEADDEADDEADDEAD;
|
default: o = 64'hDEADDEADDEADDEAD;
|
endcase
|
endcase
|
end
|
end
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (rst)
|
if (rst)
|
adrDone <= TRUE;
|
adrDone <= TRUE;
|
else begin
|
else begin
|
if (ld)
|
if (ld)
|
adrDone <= FALSE;
|
adrDone <= FALSE;
|
else if (mem|shift)
|
else if (mem|shift)
|
adrDone <= TRUE;
|
adrDone <= TRUE;
|
end
|
end
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (rst)
|
if (rst)
|
adrIdle <= TRUE;
|
adrIdle <= TRUE;
|
else begin
|
else begin
|
if (ld)
|
if (ld)
|
adrIdle <= FALSE;
|
adrIdle <= FALSE;
|
else if (mem|shift)
|
else if (mem|shift)
|
adrIdle <= TRUE;
|
adrIdle <= TRUE;
|
end
|
end
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
case(instr[`INSTRUCTION_OP])
|
case(instr[`INSTRUCTION_OP])
|
`R2:
|
`R2:
|
if (instr[`INSTRUCTION_L2]==2'b01)
|
if (instr[`INSTRUCTION_L2]==2'b01)
|
case(instr[47:42])
|
case(instr[47:42])
|
`ADD,`SUB,
|
`ADD,`SUB,
|
`AND,`OR,`XOR,`NAND,`NOR,`XNOR,
|
`AND,`OR,`XOR,`NAND,`NOR,`XNOR,
|
`SHIFTR:
|
`SHIFTR:
|
case(instr[41:36])
|
case(instr[41:36])
|
`R1:
|
`R1:
|
case(instr[22:18])
|
case(instr[22:18])
|
`COM: addro[63:0] = ~shift8;
|
`COM: addro[63:0] = ~shift8;
|
`NOT: addro[63:0] = ~|shift8;
|
`NOT: addro[63:0] = ~|shift8;
|
`NEG: addro[63:0] = -shift8;
|
`NEG: addro[63:0] = -shift8;
|
default: addro[63:0] = 64'hDCDCDCDCDCDCDCDC;
|
default: addro[63:0] = 64'hDCDCDCDCDCDCDCDC;
|
endcase
|
endcase
|
`ADD: addro[63:0] = shift8 + c;
|
`ADD: addro[63:0] = shift8 + c;
|
`SUB: addro[63:0] = shift8 - c;
|
`SUB: addro[63:0] = shift8 - c;
|
`AND: addro[63:0] = shift8 & c;
|
`AND: addro[63:0] = shift8 & c;
|
`OR: addro[63:0] = shift8 | c;
|
`OR: addro[63:0] = shift8 | c;
|
`XOR: addro[63:0] = shift8 ^ c;
|
`XOR: addro[63:0] = shift8 ^ c;
|
default: addro[63:0] = 64'hDCDCDCDCDCDCDCDC;
|
default: addro[63:0] = 64'hDCDCDCDCDCDCDCDC;
|
endcase
|
endcase
|
default: addro[63:0] = 64'hDCDCDCDCDCDCDCDC;
|
default: addro[63:0] = 64'hDCDCDCDCDCDCDCDC;
|
endcase
|
endcase
|
else
|
else
|
addro = 64'hCCCCCCCCCCCCCCCE;
|
addro = 64'hCCCCCCCCCCCCCCCE;
|
default: addro = 64'hCCCCCCCCCCCCCCCE;
|
default: addro = 64'hCCCCCCCCCCCCCCCE;
|
endcase
|
endcase
|
|
|
reg sao_done, sao_idle;
|
reg sao_done, sao_idle;
|
always @(posedge clk)
|
always @(posedge clk)
|
if (rst) begin
|
if (rst) begin
|
sao_done <= 1'b1;
|
sao_done <= 1'b1;
|
sao_idle <= 1'b1;
|
sao_idle <= 1'b1;
|
end
|
end
|
else begin
|
else begin
|
if (ld & IsShiftAndOp(instr) & BIG) begin
|
if (ld & IsShiftAndOp(instr) & BIG) begin
|
sao_done <= 1'b0;
|
sao_done <= 1'b0;
|
sao_idle <= 1'b0;
|
sao_idle <= 1'b0;
|
end
|
end
|
else begin
|
else begin
|
if (IsShiftAndOp(instr) & BIG) begin
|
if (IsShiftAndOp(instr) & BIG) begin
|
sao_done <= 1'b1;
|
sao_done <= 1'b1;
|
sao_idle <= 1'b1;
|
sao_idle <= 1'b1;
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
// Generate done signal
|
// Generate done signal
|
always @*
|
always @*
|
if (rst)
|
if (rst)
|
done <= TRUE;
|
done <= TRUE;
|
else begin
|
else begin
|
if (IsMul(instr)) begin
|
if (IsMul(instr)) begin
|
case(sz)
|
case(sz)
|
byt,byt_para: done <= mult_done80;
|
byt,byt_para: done <= mult_done80;
|
char,char_para: done <= mult_done160;
|
char,char_para: done <= mult_done160;
|
half,half_para: done <= mult_done320;
|
half,half_para: done <= mult_done320;
|
default: done <= mult_done;
|
default: done <= mult_done;
|
endcase
|
endcase
|
end
|
end
|
else if (IsDivmod(instr) & BIG)
|
else if (IsDivmod(instr) & BIG)
|
done <= div_done;
|
done <= div_done;
|
else if (IsShiftAndOp(instr) & BIG)
|
else if (IsShiftAndOp(instr) & BIG)
|
done <= sao_done;
|
done <= sao_done;
|
else if (shift)
|
else if (shift)
|
done <= adrDone;
|
done <= adrDone;
|
else if (tlb & BIG)
|
|
done <= tlb_done;
|
|
else
|
else
|
done <= TRUE;
|
done <= TRUE;
|
end
|
end
|
|
|
// Generate idle signal
|
// Generate idle signal
|
always @*
|
always @*
|
if (rst)
|
if (rst)
|
idle <= TRUE;
|
idle <= TRUE;
|
else begin
|
else begin
|
if (IsMul(instr)) begin
|
if (IsMul(instr)) begin
|
case(sz)
|
case(sz)
|
byt,byt_para: idle <= mult_idle80;
|
byt,byt_para: idle <= mult_idle80;
|
char,char_para: idle <= mult_idle160;
|
char,char_para: idle <= mult_idle160;
|
half,half_para: idle <= mult_idle320;
|
half,half_para: idle <= mult_idle320;
|
default: idle <= mult_idle;
|
default: idle <= mult_idle;
|
endcase
|
endcase
|
end
|
end
|
else if (IsDivmod(instr) & BIG)
|
else if (IsDivmod(instr) & BIG)
|
idle <= div_idle;
|
idle <= div_idle;
|
else if (IsShiftAndOp(instr) & BIG)
|
else if (IsShiftAndOp(instr) & BIG)
|
idle <= sao_idle;
|
idle <= sao_idle;
|
else if (shift)
|
else if (shift)
|
idle <= adrIdle;
|
idle <= adrIdle;
|
else if (tlb & BIG)
|
|
idle <= tlb_idle;
|
|
else
|
else
|
idle <= TRUE;
|
idle <= TRUE;
|
end
|
end
|
|
|
function fnOverflow;
|
function fnOverflow;
|
input op; // 0 = add, 1=sub
|
input op; // 0 = add, 1=sub
|
input a;
|
input a;
|
input b;
|
input b;
|
input s;
|
input s;
|
fnOverflow = (op ^ s ^ b) & (~op ^ a ^ b);
|
fnOverflow = (op ^ s ^ b) & (~op ^ a ^ b);
|
endfunction
|
endfunction
|
|
|
always @*
|
always @*
|
begin
|
begin
|
//if ((tgt[4:0]==5'd31 || tgt[4:0]==5'd30) && (o[ABW-1:0] < {sbl[50:13],13'd0} || o[ABW-1:0] > {pl[50:0],13'h1FFF}))
|
//if ((tgt[4:0]==5'd31 || tgt[4:0]==5'd30) && (o[ABW-1:0] < {sbl[50:13],13'd0} || o[ABW-1:0] > {pl[50:0],13'h1FFF}))
|
// exc <= `FLT_STK;
|
// exc <= `FLT_STK;
|
//else
|
//else
|
case(instr[`INSTRUCTION_OP])
|
case(instr[`INSTRUCTION_OP])
|
`R2:
|
`R2:
|
case(instr[`INSTRUCTION_S2])
|
case(instr[`INSTRUCTION_S2])
|
`ADD: exc <= (fnOverflow(0,a[63],b[63],o[63]) & excen[0] & instr[24]) ? `FLT_OFL : `FLT_NONE;
|
`ADD: exc <= (fnOverflow(0,a[63],b[63],o[63]) & excen[0] & instr[24]) ? `FLT_OFL : `FLT_NONE;
|
`SUB: exc <= (fnOverflow(1,a[63],b[63],o[63]) & excen[1] & instr[24]) ? `FLT_OFL : `FLT_NONE;
|
`SUB: exc <= (fnOverflow(1,a[63],b[63],o[63]) & excen[1] & instr[24]) ? `FLT_OFL : `FLT_NONE;
|
// `ASL,`ASLI: exc <= (BIG & aslo & excen[2]) ? `FLT_OFL : `FLT_NONE;
|
// `ASL,`ASLI: exc <= (BIG & aslo & excen[2]) ? `FLT_OFL : `FLT_NONE;
|
`MUL,`MULSU: exc <= prod[63] ? (prod[127:64] != 64'hFFFFFFFFFFFFFFFF && excen[3] ? `FLT_OFL : `FLT_NONE ):
|
`MUL,`MULSU: exc <= prod[63] ? (prod[127:64] != 64'hFFFFFFFFFFFFFFFF && excen[3] ? `FLT_OFL : `FLT_NONE ):
|
(prod[127:64] != 64'd0 && excen[3] ? `FLT_OFL : `FLT_NONE);
|
(prod[127:64] != 64'd0 && excen[3] ? `FLT_OFL : `FLT_NONE);
|
`FXMUL: exc <= prod[95] ? (prod[127:96] != 32'hFFFFFFFF && excen[3] ? `FLT_OFL : `FLT_NONE ):
|
`FXMUL: exc <= prod[95] ? (prod[127:96] != 32'hFFFFFFFF && excen[3] ? `FLT_OFL : `FLT_NONE ):
|
(prod[127:96] != 32'd0 && excen[3] ? `FLT_OFL : `FLT_NONE);
|
(prod[127:96] != 32'd0 && excen[3] ? `FLT_OFL : `FLT_NONE);
|
`MULU: exc <= prod[127:64] != 64'd0 && excen[3] ? `FLT_OFL : `FLT_NONE;
|
`MULU: exc <= prod[127:64] != 64'd0 && excen[3] ? `FLT_OFL : `FLT_NONE;
|
`DIV,`DIVSU,`DIVU: exc <= BIG && excen[4] & divByZero ? `FLT_DBZ : `FLT_NONE;
|
`DIV,`DIVSU,`DIVU: exc <= BIG && excen[4] & divByZero ? `FLT_DBZ : `FLT_NONE;
|
`MOD,`MODSU,`MODU: exc <= BIG && excen[4] & divByZero ? `FLT_DBZ : `FLT_NONE;
|
`MOD,`MODSU,`MODU: exc <= BIG && excen[4] & divByZero ? `FLT_DBZ : `FLT_NONE;
|
default: exc <= `FLT_NONE;
|
default: exc <= `FLT_NONE;
|
endcase
|
endcase
|
`MULI: exc <= prod[63] ? (prod[127:64] != 64'hFFFFFFFFFFFFFFFF & excen[3] ? `FLT_OFL : `FLT_NONE):
|
`MULI: exc <= prod[63] ? (prod[127:64] != 64'hFFFFFFFFFFFFFFFF & excen[3] ? `FLT_OFL : `FLT_NONE):
|
(prod[127:64] != 64'd0 & excen[3] ? `FLT_OFL : `FLT_NONE);
|
(prod[127:64] != 64'd0 & excen[3] ? `FLT_OFL : `FLT_NONE);
|
`DIVI: exc <= BIG & excen[4] & divByZero & instr[27] ? `FLT_DBZ : `FLT_NONE;
|
`DIVI: exc <= BIG & excen[4] & divByZero & instr[27] ? `FLT_DBZ : `FLT_NONE;
|
`MODI: exc <= BIG & excen[4] & divByZero & instr[27] ? `FLT_DBZ : `FLT_NONE;
|
`MODI: exc <= BIG & excen[4] & divByZero & instr[27] ? `FLT_DBZ : `FLT_NONE;
|
`CSRRW: exc <= (instr[27:21]==7'b0011011) ? `FLT_SEG : `FLT_NONE;
|
`CSRRW: exc <= (instr[27:21]==7'b0011011) ? `FLT_SEG : `FLT_NONE;
|
`MEMNDX:
|
`MEMNDX:
|
begin
|
begin
|
`ifdef SUPPORT_BBMS
|
`ifdef SUPPORT_BBMS
|
if ((Ra[4:0]==5'd30 || Ra[4:0]==5'd31) && (usa < {sbl[50:0],13'd0} || usa > {sbu[50:0],13'h1FF8}) && dl!=2'b00)
|
if ((Ra[4:0]==5'd30 || Ra[4:0]==5'd31) && (usa < {sbl[50:0],13'd0} || usa > {sbu[50:0],13'h1FF8}) && dl!=2'b00)
|
exc <= `FLT_STK;
|
exc <= `FLT_STK;
|
else if (usa > {sbu[50:0],13'h1FFF} && dl!=2'b00)
|
else if (usa > {sbu[50:0],13'h1FFF} && dl!=2'b00)
|
exc <= `FLT_SGB;
|
exc <= `FLT_SGB;
|
else if (usa < {sbl[50:0],13'h0000} && usa > {dbu[50:0],13'h1fff} && dl!=2'b00)
|
else if (usa < {sbl[50:0],13'h0000} && usa > {dbu[50:0],13'h1fff} && dl!=2'b00)
|
exc <= `FLT_SGB;
|
exc <= `FLT_SGB;
|
else if (usa > {en[50:0],13'h1fff} && usa < {dbl[50:0],13'd0} && dl!=2'b00)
|
else if (usa > {en[50:0],13'h1fff} && usa < {dbl[50:0],13'd0} && dl!=2'b00)
|
exc <= `FLT_SGB;
|
exc <= `FLT_SGB;
|
else if (usa < {ro[50:0],13'd0} && store && dl!=2'b00)
|
else if (usa < {ro[50:0],13'd0} && store && dl!=2'b00)
|
exc <= `FLT_WRV;
|
exc <= `FLT_WRV;
|
else
|
else
|
`endif
|
`endif
|
begin
|
begin
|
if (instr[7:6]==2'b10) begin
|
if (instr[7:6]==2'b10) begin
|
if (instr[31])
|
if (instr[31])
|
case({instr[31:28],instr[17:16]})
|
case({instr[31:28],instr[17:16]})
|
`PUSH: exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
|
`PUSH: exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
|
default: exc <= `FLT_UNIMP;
|
default: exc <= `FLT_UNIMP;
|
endcase
|
endcase
|
else
|
else
|
exc <= `FLT_UNIMP;
|
exc <= `FLT_UNIMP;
|
end
|
end
|
else if (instr[7:6]==2'b00) begin
|
else if (instr[7:6]==2'b00) begin
|
if (!instr[31]) begin
|
if (!instr[31]) begin
|
if (BIG) begin
|
if (BIG) begin
|
case({instr[31:28],instr[22:21]})
|
case({instr[31:28],instr[22:21]})
|
`LBX,`LBUX,`LVBX,`LVBUX: exc <= `FLT_NONE;
|
`LBX,`LBUX,`LVBX,`LVBUX: exc <= `FLT_NONE;
|
`LCX,`LCUX,`LVCX,`LVCUX: exc <= o[ 0] ? `FLT_ALN : `FLT_NONE;
|
`LCX,`LCUX,`LVCX,`LVCUX: exc <= o[ 0] ? `FLT_ALN : `FLT_NONE;
|
`LVHX,`LVHUX,`LHX,`LHUX: exc <= |o[1:0] ? `FLT_ALN : `FLT_NONE;
|
`LVHX,`LVHUX,`LHX,`LHUX: exc <= |o[1:0] ? `FLT_ALN : `FLT_NONE;
|
`LWX,`LVWX,`LWRX,
|
`LWX,`LVWX,`LWRX,
|
`CACHEX,`LVX: exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
|
`CACHEX,`LVX: exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
|
`LVX,`SVX,`LVWS,`SVWS: exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
|
`LVX,`SVX,`LVWS,`SVWS: exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
|
default: exc <= `FLT_UNIMP;
|
default: exc <= `FLT_UNIMP;
|
endcase
|
endcase
|
end
|
end
|
else
|
else
|
exc <= `FLT_UNIMP;
|
exc <= `FLT_UNIMP;
|
end
|
end
|
else begin
|
else begin
|
if (BIG) begin
|
if (BIG) begin
|
case({instr[31:28],instr[17:16]})
|
case({instr[31:28],instr[17:16]})
|
`PUSH: exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
|
`PUSH: exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
|
`SBX: exc <= `FLT_NONE;
|
`SBX: exc <= `FLT_NONE;
|
`SCX: exc <= o[ 0] ? `FLT_ALN : `FLT_NONE;
|
`SCX: exc <= o[ 0] ? `FLT_ALN : `FLT_NONE;
|
`SHX: exc <= |o[1:0] ? `FLT_ALN : `FLT_NONE;
|
`SHX: exc <= |o[1:0] ? `FLT_ALN : `FLT_NONE;
|
`SWX,`SWCX: exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
|
`SWX,`SWCX: exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
|
`SVX: exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
|
`SVX: exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
|
`SVWS: exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
|
`SVWS: exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
|
default: exc <= `FLT_UNIMP;
|
default: exc <= `FLT_UNIMP;
|
endcase
|
endcase
|
end
|
end
|
else
|
else
|
exc <= `FLT_UNIMP;
|
exc <= `FLT_UNIMP;
|
end
|
end
|
end
|
end
|
else
|
else
|
exc <= `FLT_UNIMP;
|
exc <= `FLT_UNIMP;
|
end
|
end
|
end
|
end
|
`ifdef SUPPORT_BBMS
|
`ifdef SUPPORT_BBMS
|
`LB,`LBU,`SB:
|
`LB,`LBU,`SB:
|
if ((Ra[4:0]==5'd30 || Ra[4:0]==5'd31) && (usa < {sbl[50:0],13'd0} || usa > {sbu[50:0],13'h1FF8}) && dl!=2'b00)
|
if ((Ra[4:0]==5'd30 || Ra[4:0]==5'd31) && (usa < {sbl[50:0],13'd0} || usa > {sbu[50:0],13'h1FF8}) && dl!=2'b00)
|
exc <= `FLT_STK;
|
exc <= `FLT_STK;
|
else if (usa > {sbu[50:0],13'h1FFF} && dl!=2'b00)
|
else if (usa > {sbu[50:0],13'h1FFF} && dl!=2'b00)
|
exc <= `FLT_SGB;
|
exc <= `FLT_SGB;
|
else if (usa < {sbl[50:0],13'h0000} && usa > {dbu[50:0],13'h1fff} && dl!=2'b00)
|
else if (usa < {sbl[50:0],13'h0000} && usa > {dbu[50:0],13'h1fff} && dl!=2'b00)
|
exc <= `FLT_SGB;
|
exc <= `FLT_SGB;
|
else if (usa > {en[50:0],13'h1fff} && usa < {dbl[50:0],13'd0} && dl!=2'b00)
|
else if (usa > {en[50:0],13'h1fff} && usa < {dbl[50:0],13'd0} && dl!=2'b00)
|
exc <= `FLT_SGB;
|
exc <= `FLT_SGB;
|
else if (usa < {ro[50:0],13'd0} && store && dl!=2'b00)
|
else if (usa < {ro[50:0],13'd0} && store && dl!=2'b00)
|
exc <= `FLT_WRV;
|
exc <= `FLT_WRV;
|
`endif
|
`endif
|
`Lx,`Sx,`LxU,`LVx,`LVxU:
|
`Lx,`Sx,`LxU,`LVx,`LVxU:
|
begin
|
begin
|
`ifdef SUPPORT_BBMS
|
`ifdef SUPPORT_BBMS
|
if ((Ra[4:0]==5'd30 || Ra[4:0]==5'd31) && (usa < {sbl[50:0],13'd0} || usa > {sbu[50:0],13'h1FF8}) && dl!=2'b00)
|
if ((Ra[4:0]==5'd30 || Ra[4:0]==5'd31) && (usa < {sbl[50:0],13'd0} || usa > {sbu[50:0],13'h1FF8}) && dl!=2'b00)
|
exc <= `FLT_STK;
|
exc <= `FLT_STK;
|
else if (usa > {sbu[50:0],13'h1FFF} && dl!=2'b00)
|
else if (usa > {sbu[50:0],13'h1FFF} && dl!=2'b00)
|
exc <= `FLT_SGB;
|
exc <= `FLT_SGB;
|
else if (usa < {sbl[50:0],13'h0000} && usa > {dbu[50:0],13'h1fff} && dl!=2'b00)
|
else if (usa < {sbl[50:0],13'h0000} && usa > {dbu[50:0],13'h1fff} && dl!=2'b00)
|
exc <= `FLT_SGB;
|
exc <= `FLT_SGB;
|
else if (usa > {en[50:0],13'h1fff} && usa < {dbl[50:0],13'd0} && dl!=2'b00)
|
else if (usa > {en[50:0],13'h1fff} && usa < {dbl[50:0],13'd0} && dl!=2'b00)
|
exc <= `FLT_SGB;
|
exc <= `FLT_SGB;
|
else if (usa < {ro[50:0],13'd0} && store && dl!=2'b00)
|
else if (usa < {ro[50:0],13'd0} && store && dl!=2'b00)
|
exc <= `FLT_WRV;
|
exc <= `FLT_WRV;
|
else
|
else
|
`endif
|
`endif
|
casez(b[2:0])
|
casez(b[2:0])
|
3'b100: exc <= o[2:0]!=3'b0 ? `FLT_NONE : `FLT_NONE; // LW / SW
|
3'b100: exc <= (o[2:0]!=3'b0) ? `FLT_NONE : `FLT_NONE; // LW / SW
|
3'b?10: exc <= o[1:0]!=2'b0 ? `FLT_ALN : `FLT_NONE; // LH / LHU / SH
|
3'b?10: exc <= (o[1:0]!=2'b0) ? `FLT_NONE : `FLT_NONE; // LH / LHU / SH
|
default: exc <= o[ 0] ? `FLT_ALN : `FLT_NONE; // LC / LCU / SC
|
default: exc <= o[ 0] ? `FLT_NONE : `FLT_NONE; // LC / LCU / SC
|
endcase
|
endcase
|
end
|
end
|
`LWR,`SWC,`CAS,`CACHE:
|
`LWR,`SWC,`CAS,`CACHE:
|
begin
|
begin
|
`ifdef SUPPORT_BBMS
|
`ifdef SUPPORT_BBMS
|
if ((Ra[4:0]==5'd30 || Ra[4:0]==5'd31) && (usa < {sbl[50:0],13'd0} || usa > {sbu[50:0],13'h1FF8}) && dl!=2'b00)
|
if ((Ra[4:0]==5'd30 || Ra[4:0]==5'd31) && (usa < {sbl[50:0],13'd0} || usa > {sbu[50:0],13'h1FF8}) && dl!=2'b00)
|
exc <= `FLT_STK;
|
exc <= `FLT_STK;
|
else if (usa > {sbu[50:0],13'h1FFF} && dl!=2'b00)
|
else if (usa > {sbu[50:0],13'h1FFF} && dl!=2'b00)
|
exc <= `FLT_SGB;
|
exc <= `FLT_SGB;
|
else if (usa < {sbl[50:0],13'h0000} && usa > {dbu[50:0],13'h1fff} && dl!=2'b00)
|
else if (usa < {sbl[50:0],13'h0000} && usa > {dbu[50:0],13'h1fff} && dl!=2'b00)
|
exc <= `FLT_SGB;
|
exc <= `FLT_SGB;
|
else if (usa > {en[50:0],13'h1fff} && usa < {dbl[50:0],13'd0} && dl!=2'b00)
|
else if (usa > {en[50:0],13'h1fff} && usa < {dbl[50:0],13'd0} && dl!=2'b00)
|
exc <= `FLT_SGB;
|
exc <= `FLT_SGB;
|
else if (usa < {ro[50:0],13'd0} && store && dl!=2'b00)
|
else if (usa < {ro[50:0],13'd0} && store && dl!=2'b00)
|
exc <= `FLT_WRV;
|
exc <= `FLT_WRV;
|
else
|
else
|
`endif
|
`endif
|
exc <= o[2:0]!=3'b0 ? `FLT_ALN : `FLT_NONE;
|
exc <= o[2:0]!=3'b0 ? `FLT_ALN : `FLT_NONE;
|
end
|
end
|
default: exc <= `FLT_NONE;
|
default: exc <= `FLT_NONE;
|
endcase
|
endcase
|
end
|
end
|
|
|
reg [63:0] aa, bb;
|
reg [63:0] aa, bb;
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
begin
|
begin
|
aa <= shfto;
|
aa <= shfto;
|
bb <= c;
|
bb <= c;
|
end
|
end
|
|
|
task tskSeq;
|
task tskSeq;
|
input [47:0] instr;
|
input [47:0] instr;
|
input [2:0] sz;
|
input [2:0] sz;
|
input [63:0] a;
|
input [63:0] a;
|
input [63:0] b;
|
input [63:0] b;
|
output [63:0] o;
|
output [63:0] o;
|
begin
|
begin
|
`ifdef SIMD
|
`ifdef SIMD
|
case(sz[2:0])
|
case(sz[2:0])
|
3'd0: o[63:0] = $signed(a[7:0]) == $signed(b[7:0]);
|
3'd0: o[63:0] = $signed(a[7:0]) == $signed(b[7:0]);
|
3'd1: o[63:0] = $signed(a[15:0]) == $signed(b[15:0]);
|
3'd1: o[63:0] = $signed(a[15:0]) == $signed(b[15:0]);
|
3'd2: o[63:0] = $signed(a[31:0]) == $signed(b[31:0]);
|
3'd2: o[63:0] = $signed(a[31:0]) == $signed(b[31:0]);
|
3'd3: o[63:0] = $signed(a) == $signed(b);
|
3'd3: o[63:0] = $signed(a) == $signed(b);
|
3'd4: o[63:0] = {
|
3'd4: o[63:0] = {
|
7'h0,$signed(a[7:0]) == $signed(b[7:0]),
|
7'h0,$signed(a[63:56]) == $signed(b[63:56]),
|
7'h0,$signed(a[15:8]) == $signed(b[15:8]),
|
|
7'h0,$signed(a[23:16]) == $signed(b[23:16]),
|
|
7'h0,$signed(a[31:24]) == $signed(b[31:24]),
|
|
7'h0,$signed(a[39:32]) == $signed(b[39:32]),
|
|
7'h0,$signed(a[47:40]) == $signed(b[47:40]),
|
|
7'h0,$signed(a[55:48]) == $signed(b[55:48]),
|
7'h0,$signed(a[55:48]) == $signed(b[55:48]),
|
7'h0,$signed(a[63:56]) == $signed(b[63:56])
|
7'h0,$signed(a[47:40]) == $signed(b[47:40]),
|
|
7'h0,$signed(a[39:32]) == $signed(b[39:32]),
|
|
7'h0,$signed(a[31:24]) == $signed(b[31:24]),
|
|
7'h0,$signed(a[23:16]) == $signed(b[23:16]),
|
|
7'h0,$signed(a[15:8]) == $signed(b[15:8]),
|
|
7'h0,$signed(a[7:0]) == $signed(b[7:0])
|
};
|
};
|
3'd5: o[63:0] = {
|
3'd5: o[63:0] = {
|
15'h0,$signed(a[15:0]) == $signed(b[15:0]),
|
15'h0,$signed(a[63:48]) == $signed(b[63:48]),
|
15'h0,$signed(a[31:16]) == $signed(b[31:16]),
|
|
15'h0,$signed(a[47:32]) == $signed(b[47:32]),
|
15'h0,$signed(a[47:32]) == $signed(b[47:32]),
|
15'h0,$signed(a[63:48]) == $signed(b[63:48])
|
15'h0,$signed(a[31:16]) == $signed(b[31:16]),
|
|
15'h0,$signed(a[15:0]) == $signed(b[15:0])
|
};
|
};
|
3'd6: o[63:0] = {
|
3'd6: o[63:0] = {
|
31'h0,$signed(a[31:0]) == $signed(b[31:0]),
|
31'h0,$signed(a[63:32]) == $signed(b[63:32]),
|
31'h0,$signed(a[63:32]) == $signed(b[63:32])
|
31'h0,$signed(a[31:0]) == $signed(b[31:0])
|
};
|
};
|
3'd7: o[63:0] = $signed(a[63:0]) == $signed(b[63:0]);
|
3'd7: o[63:0] = $signed(a[63:0]) == $signed(b[63:0]);
|
endcase
|
endcase
|
`else
|
`else
|
o = $signed(a) == $signed(b);
|
o = $signed(a) == $signed(b);
|
`endif
|
`endif
|
end
|
end
|
endtask
|
endtask
|
|
|
task tskSlt;
|
task tskSlt;
|
input [47:0] instr;
|
input [47:0] instr;
|
input [2:0] sz;
|
input [2:0] sz;
|
input [63:0] a;
|
input [63:0] a;
|
input [63:0] b;
|
input [63:0] b;
|
output [63:0] o;
|
output [63:0] o;
|
begin
|
begin
|
`ifdef SIMD
|
`ifdef SIMD
|
case(sz[2:0])
|
case(sz[2:0])
|
3'd0: o[63:0] = $signed(a[7:0]) < $signed(b[7:0]);
|
3'd0: o[63:0] = $signed(a[7:0]) < $signed(b[7:0]);
|
3'd1: o[63:0] = $signed(a[15:0]) < $signed(b[15:0]);
|
3'd1: o[63:0] = $signed(a[15:0]) < $signed(b[15:0]);
|
3'd2: o[63:0] = $signed(a[31:0]) < $signed(b[31:0]);
|
3'd2: o[63:0] = $signed(a[31:0]) < $signed(b[31:0]);
|
3'd3: o[63:0] = $signed(a) < $signed(b);
|
3'd3: o[63:0] = $signed(a) < $signed(b);
|
3'd4: o[63:0] = {
|
3'd4: o[63:0] = {
|
7'h0,$signed(a[7:0]) < $signed(b[7:0]),
|
7'h0,$signed(a[63:56]) < $signed(b[63:56]),
|
7'h0,$signed(a[15:8]) < $signed(b[15:8]),
|
|
7'h0,$signed(a[23:16]) < $signed(b[23:16]),
|
|
7'h0,$signed(a[31:24]) < $signed(b[31:24]),
|
|
7'h0,$signed(a[39:32]) < $signed(b[39:32]),
|
|
7'h0,$signed(a[47:40]) < $signed(b[47:40]),
|
|
7'h0,$signed(a[55:48]) < $signed(b[55:48]),
|
7'h0,$signed(a[55:48]) < $signed(b[55:48]),
|
7'h0,$signed(a[63:56]) < $signed(b[63:56])
|
7'h0,$signed(a[47:40]) < $signed(b[47:40]),
|
|
7'h0,$signed(a[39:32]) < $signed(b[39:32]),
|
|
7'h0,$signed(a[31:24]) < $signed(b[31:24]),
|
|
7'h0,$signed(a[23:16]) < $signed(b[23:16]),
|
|
7'h0,$signed(a[15:8]) < $signed(b[15:8]),
|
|
7'h0,$signed(a[7:0]) < $signed(b[7:0])
|
};
|
};
|
3'd5: o[63:0] = {
|
3'd5: o[63:0] = {
|
15'h0,$signed(a[15:0]) < $signed(b[15:0]),
|
15'h0,$signed(a[63:48]) < $signed(b[63:48]),
|
15'h0,$signed(a[31:16]) < $signed(b[31:16]),
|
|
15'h0,$signed(a[47:32]) < $signed(b[47:32]),
|
15'h0,$signed(a[47:32]) < $signed(b[47:32]),
|
15'h0,$signed(a[63:48]) < $signed(b[63:48])
|
15'h0,$signed(a[31:16]) < $signed(b[31:16]),
|
|
15'h0,$signed(a[15:0]) < $signed(b[15:0])
|
};
|
};
|
3'd6: o[63:0] = {
|
3'd6: o[63:0] = {
|
31'h0,$signed(a[31:0]) < $signed(b[31:0]),
|
31'h0,$signed(a[63:32]) < $signed(b[63:32]),
|
31'h0,$signed(a[63:32]) < $signed(b[63:32])
|
31'h0,$signed(a[31:0]) < $signed(b[31:0])
|
};
|
};
|
3'd7: o[63:0] = $signed(a[63:0]) < $signed(b[63:0]);
|
3'd7: o[63:0] = $signed(a[63:0]) < $signed(b[63:0]);
|
endcase
|
endcase
|
`else
|
`else
|
o[63:0] = $signed(a[63:0]) < $signed(b[63:0]);
|
o[63:0] = $signed(a[63:0]) < $signed(b[63:0]);
|
`endif
|
`endif
|
end
|
end
|
endtask
|
endtask
|
|
|
task tskSle;
|
task tskSle;
|
input [47:0] instr;
|
input [47:0] instr;
|
input [2:0] sz;
|
input [2:0] sz;
|
input [63:0] a;
|
input [63:0] a;
|
input [63:0] b;
|
input [63:0] b;
|
output [63:0] o;
|
output [63:0] o;
|
begin
|
begin
|
`ifdef SIMD
|
`ifdef SIMD
|
case(sz[2:0])
|
case(sz[2:0])
|
3'd0: o[63:0] = $signed(a[7:0]) <= $signed(b[7:0]);
|
3'd0: o[63:0] = $signed(a[7:0]) <= $signed(b[7:0]);
|
3'd1: o[63:0] = $signed(a[15:0]) <= $signed(b[15:0]);
|
3'd1: o[63:0] = $signed(a[15:0]) <= $signed(b[15:0]);
|
3'd2: o[63:0] = $signed(a[31:0]) <= $signed(b[31:0]);
|
3'd2: o[63:0] = $signed(a[31:0]) <= $signed(b[31:0]);
|
3'd3: o[63:0] = $signed(a) <= $signed(b);
|
3'd3: o[63:0] = $signed(a) <= $signed(b);
|
3'd4: o[63:0] = {
|
3'd4: o[63:0] = {
|
7'h0,$signed(a[7:0]) <= $signed(b[7:0]),
|
7'h0,$signed(a[63:56]) <= $signed(b[63:56]),
|
7'h0,$signed(a[15:8]) <= $signed(b[15:8]),
|
|
7'h0,$signed(a[23:16]) <= $signed(b[23:16]),
|
|
7'h0,$signed(a[31:24]) <= $signed(b[31:24]),
|
|
7'h0,$signed(a[39:32]) <= $signed(b[39:32]),
|
|
7'h0,$signed(a[47:40]) <= $signed(b[47:40]),
|
|
7'h0,$signed(a[55:48]) <= $signed(b[55:48]),
|
7'h0,$signed(a[55:48]) <= $signed(b[55:48]),
|
7'h0,$signed(a[63:56]) <= $signed(b[63:56])
|
7'h0,$signed(a[47:40]) <= $signed(b[47:40]),
|
|
7'h0,$signed(a[39:32]) <= $signed(b[39:32]),
|
|
7'h0,$signed(a[31:24]) <= $signed(b[31:24]),
|
|
7'h0,$signed(a[23:16]) <= $signed(b[23:16]),
|
|
7'h0,$signed(a[15:8]) <= $signed(b[15:8]),
|
|
7'h0,$signed(a[7:0]) <= $signed(b[7:0])
|
};
|
};
|
3'd5: o[63:0] = {
|
3'd5: o[63:0] = {
|
15'h0,$signed(a[15:0]) <= $signed(b[15:0]),
|
15'h0,$signed(a[63:48]) <= $signed(b[63:48]),
|
15'h0,$signed(a[31:16]) <= $signed(b[31:16]),
|
|
15'h0,$signed(a[47:32]) <= $signed(b[47:32]),
|
15'h0,$signed(a[47:32]) <= $signed(b[47:32]),
|
15'h0,$signed(a[63:48]) <= $signed(b[63:48])
|
15'h0,$signed(a[31:16]) <= $signed(b[31:16]),
|
|
15'h0,$signed(a[15:0]) <= $signed(b[15:0])
|
};
|
};
|
3'd6: o[63:0] = {
|
3'd6: o[63:0] = {
|
31'h0,$signed(a[31:0]) <= $signed(b[31:0]),
|
31'h0,$signed(a[63:32]) <= $signed(b[63:32]),
|
31'h0,$signed(a[63:32]) <= $signed(b[63:32])
|
31'h0,$signed(a[31:0]) <= $signed(b[31:0])
|
};
|
};
|
3'd7: o[63:0] = $signed(a[63:0]) <= $signed(b[63:0]);
|
3'd7: o[63:0] = $signed(a[63:0]) <= $signed(b[63:0]);
|
endcase
|
endcase
|
`else
|
`else
|
o = $signed(a) <= $signed(b);
|
o = $signed(a) <= $signed(b);
|
`endif
|
`endif
|
end
|
end
|
endtask
|
endtask
|
|
|
task tskSltu;
|
task tskSltu;
|
input [47:0] instr;
|
input [47:0] instr;
|
input [2:0] sz;
|
input [2:0] sz;
|
input [63:0] a;
|
input [63:0] a;
|
input [63:0] b;
|
input [63:0] b;
|
output [63:0] o;
|
output [63:0] o;
|
begin
|
begin
|
`ifdef SIMD
|
`ifdef SIMD
|
case(sz[2:0])
|
case(sz[2:0])
|
3'd4,3'd0: o = {
|
3'd0: o = (a[7:0]) < (b[7:0]);
|
7'h0,(a[7:0]) < (b[7:0]),
|
3'd1: o = (a[15:0]) < (b[15:0]);
|
7'h0,(a[15:8]) < (b[15:8]),
|
3'd2: o = (a[31:0]) < (b[31:0]);
|
7'h0,(a[23:16]) < (b[23:16]),
|
3'd4: o = {
|
7'h0,(a[31:24]) < (b[31:24]),
|
7'h0,(a[63:56]) < (b[63:56]),
|
7'h0,(a[39:32]) < (b[39:32]),
|
|
7'h0,(a[47:40]) < (b[47:40]),
|
|
7'h0,(a[55:48]) < (b[55:48]),
|
7'h0,(a[55:48]) < (b[55:48]),
|
7'h0,(a[63:56]) < (b[63:56])
|
7'h0,(a[47:40]) < (b[47:40]),
|
|
7'h0,(a[39:32]) < (b[39:32]),
|
|
7'h0,(a[31:24]) < (b[31:24]),
|
|
7'h0,(a[23:16]) < (b[23:16]),
|
|
7'h0,(a[15:8]) < (b[15:8]),
|
|
7'h0,(a[7:0]) < (b[7:0])
|
};
|
};
|
3'd5,3'd1: o = {
|
3'd5: o = {
|
15'h0,(a[15:0]) < (b[15:0]),
|
15'h0,(a[63:48]) < (b[63:48]),
|
15'h0,(a[31:16]) < (b[31:16]),
|
|
15'h0,(a[47:32]) < (b[47:32]),
|
15'h0,(a[47:32]) < (b[47:32]),
|
15'h0,(a[63:48]) < (b[63:48])
|
15'h0,(a[31:16]) < (b[31:16]),
|
|
15'h0,(a[15:0]) < (b[15:0])
|
};
|
};
|
3'd6,3'd2: o = {
|
3'd6: o = {
|
31'h0,(a[31:0]) < (b[31:0]),
|
31'h0,(a[63:32]) < (b[63:32]),
|
31'h0,(a[63:32]) < (b[63:32])
|
31'h0,(a[31:0]) < (b[31:0])
|
};
|
};
|
3'd7,3'd3: o = (a[63:0]) < (b[63:0]);
|
3'd7,3'd3: o = (a[63:0]) < (b[63:0]);
|
endcase
|
endcase
|
`else
|
`else
|
o = (a) < (b);
|
o = (a) < (b);
|
`endif
|
`endif
|
end
|
end
|
endtask
|
endtask
|
|
|
task tskSleu;
|
task tskSleu;
|
input [47:0] instr;
|
input [47:0] instr;
|
input [2:0] sz;
|
input [2:0] sz;
|
input [63:0] a;
|
input [63:0] a;
|
input [63:0] b;
|
input [63:0] b;
|
output [63:0] o;
|
output [63:0] o;
|
begin
|
begin
|
`ifdef SIMD
|
`ifdef SIMD
|
case(sz[2:0])
|
case(sz[2:0])
|
3'd0: o[63:0] = (a[7:0]) <= (b[7:0]);
|
3'd0: o = (a[7:0]) <= (b[7:0]);
|
3'd1: o[63:0] = (a[15:0]) <= (b[15:0]);
|
3'd1: o = (a[15:0]) <= (b[15:0]);
|
3'd2: o[63:0] = (a[31:0]) <= (b[31:0]);
|
3'd2: o = (a[31:0]) <= (b[31:0]);
|
3'd3: o[63:0] = (a) <= (b);
|
3'd4: o = {
|
3'd4: o[63:0] = {
|
7'h0,(a[63:56]) <= (b[63:56]),
|
7'h0,(a[7:0]) <= (b[7:0]),
|
|
7'h0,(a[15:8]) <= (b[15:8]),
|
|
7'h0,(a[23:16]) <= (b[23:16]),
|
|
7'h0,(a[31:24]) <= (b[31:24]),
|
|
7'h0,(a[39:32]) <= (b[39:32]),
|
|
7'h0,(a[47:40]) <= (b[47:40]),
|
|
7'h0,(a[55:48]) <= (b[55:48]),
|
7'h0,(a[55:48]) <= (b[55:48]),
|
7'h0,(a[63:56]) <= (b[63:56])
|
7'h0,(a[47:40]) <= (b[47:40]),
|
|
7'h0,(a[39:32]) <= (b[39:32]),
|
|
7'h0,(a[31:24]) <= (b[31:24]),
|
|
7'h0,(a[23:16]) <= (b[23:16]),
|
|
7'h0,(a[15:8]) <= (b[15:8]),
|
|
7'h0,(a[7:0]) <= (b[7:0])
|
};
|
};
|
3'd5: o[63:0] = {
|
3'd5: o = {
|
15'h0,(a[15:0]) <= (b[15:0]),
|
15'h0,(a[63:48]) <= (b[63:48]),
|
15'h0,(a[31:16]) <= (b[31:16]),
|
|
15'h0,(a[47:32]) <= (b[47:32]),
|
15'h0,(a[47:32]) <= (b[47:32]),
|
15'h0,(a[63:48]) <= (b[63:48])
|
15'h0,(a[31:16]) <= (b[31:16]),
|
|
15'h0,(a[15:0]) <= (b[15:0])
|
};
|
};
|
3'd6: o[63:0] = {
|
3'd6: o = {
|
31'h0,(a[31:0]) <= (b[31:0]),
|
31'h0,(a[63:32]) <= (b[63:32]),
|
31'h0,(a[63:32]) <= (b[63:32])
|
31'h0,(a[31:0]) <= (b[31:0])
|
};
|
};
|
3'd7: o[63:0] = (a[63:0]) <= (b[63:0]);
|
3'd7,3'd3: o = (a[63:0]) <= (b[63:0]);
|
endcase
|
endcase
|
`else
|
`else
|
o[63:0] = (a[63:0]) <= (b[63:0]);
|
o[63:0] = (a[63:0]) <= (b[63:0]);
|
`endif
|
`endif
|
end
|
end
|
endtask
|
endtask
|
|
|
endmodule
|
endmodule
|
|
|