URL
https://opencores.org/ocsvn/thor/thor/trunk
Subversion Repositories thor
Compare Revisions
- This comparison shows the changes necessary to convert path
/thor/trunk/FT64v5
- from Rev 49 to Rev 50
- ↔ Reverse comparison
Rev 49 → Rev 50
/doc/FT64v5.docx
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/rtl/common/FT64_alu.v
96,16 → 96,17
input [47:0] isn; |
case(isn[`INSTRUCTION_OP]) |
`IVECTOR: |
case(isn[`INSTRUCTION_S2]) |
`VMUL,`VMULS: IsMul = TRUE; |
default: IsMul = FALSE; |
endcase |
`RR: |
case(isn[`INSTRUCTION_S2]) |
`MULU,`MULSU,`MUL: IsMul = TRUE; |
default: IsMul = FALSE; |
endcase |
`MULUI,`MULSUI,`MULI: IsMul = TRUE; |
case(isn[`INSTRUCTION_S2]) |
`VMUL,`VMULS: IsMul = TRUE; |
default: IsMul = FALSE; |
endcase |
`R2: |
case(isn[`INSTRUCTION_S2]) |
`MULU,`MULSU,`MUL: IsMul = TRUE; |
`MULUH,`MULSUH,`MULH: IsMul = TRUE; |
default: IsMul = FALSE; |
endcase |
`MULUI,`MULI: IsMul = TRUE; |
default: IsMul = FALSE; |
endcase |
endfunction |
114,15 → 115,16
input [47:0] isn; |
case(isn[`INSTRUCTION_OP]) |
`IVECTOR: |
case(isn[`INSTRUCTION_S2]) |
`VDIV,`VDIVS: IsDivmod = TRUE; |
default: IsDivmod = FALSE; |
endcase |
`RR: |
case(isn[`INSTRUCTION_S2]) |
`DIVMODU,`DIVMODSU,`DIVMOD: IsDivmod = TRUE; |
default: IsDivmod = FALSE; |
endcase |
case(isn[`INSTRUCTION_S2]) |
`VDIV,`VDIVS: IsDivmod = TRUE; |
default: IsDivmod = FALSE; |
endcase |
`R2: |
case(isn[`INSTRUCTION_S2]) |
`DIVU,`DIVSU,`DIV: IsDivmod = TRUE; |
`MODU,`MODSU,`MOD: IsDivmod = TRUE; |
default: IsDivmod = FALSE; |
endcase |
`DIVUI,`DIVI,`MODI: IsDivmod = TRUE; |
default: IsDivmod = FALSE; |
endcase |
136,11 → 138,11
`VMUL,`VMULS,`VDIV,`VDIVS: IsSgn = TRUE; |
default: IsSgn = FALSE; |
endcase |
`RR: |
case(isn[`INSTRUCTION_S2]) |
`MUL,`DIVMOD: IsSgn = TRUE; |
default: IsSgn = FALSE; |
endcase |
`R2: |
case(isn[`INSTRUCTION_S2]) |
`MUL,`DIV,`MOD,`MULH: IsSgn = TRUE; |
default: IsSgn = FALSE; |
endcase |
`MULI,`DIVI,`MODI: IsSgn = TRUE; |
default: IsSgn = FALSE; |
endcase |
149,11 → 151,11
function IsSgnus; |
input [47:0] isn; |
case(isn[`INSTRUCTION_OP]) |
`RR: |
case(isn[`INSTRUCTION_S2]) |
`MULSU,`DIVMODSU: IsSgnus = TRUE; |
default: IsSgnus = FALSE; |
endcase |
`R2: |
case(isn[`INSTRUCTION_S2]) |
`MULSU,`MULSUH,`DIVSU,`MODSU: IsSgnus = TRUE; |
default: IsSgnus = FALSE; |
endcase |
default: IsSgnus = FALSE; |
endcase |
endfunction |
719,12 → 721,15
o[63:0] = (a!=64'd0) ? b : c; |
`MUX: for (n = 0; n < 64; n = n + 1) |
o[n] <= a[n] ? b[n] : c[n]; |
`MULU: o[63:0] = instr[25:24]==2'b00 ? prod[DBW-1:0] : prod[DBW*2-1:DBW]; |
`MULSU: o[63:0] = instr[25:24]==2'b00 ? prod[DBW-1:0] : prod[DBW*2-1:DBW]; |
`MUL: o[63:0] = instr[25:24]==2'b00 ? prod[DBW-1:0] : prod[DBW*2-1:DBW]; |
`DIVMODU: o[63:0] = BIG ? (instr[25:24]==2'b00 ? divq : rem) : 64'hCCCCCCCCCCCCCCCC; |
`DIVMODSU: o[63:0] = BIG ? (instr[25:24]==2'b00 ? divq : rem) : 64'hCCCCCCCCCCCCCCCC; |
`DIVMOD: o[63:0] = BIG ? (instr[25:24]==2'b00 ? divq : rem) : 64'hCCCCCCCCCCCCCCCC; |
`MULU: o[63:0] = prod[DBW-1:0]; |
`MULSU: o[63:0] = prod[DBW-1:0]; |
`MUL: o[63:0] = prod[DBW-1:0]; |
`DIVU: o[63:0] = BIG ? divq : 64'hCCCCCCCCCCCCCCCC; |
`DIVSU: o[63:0] = BIG ? divq : 64'hCCCCCCCCCCCCCCCC; |
`DIV: o[63:0] = BIG ? divq : 64'hCCCCCCCCCCCCCCCC; |
`MODU: o[63:0] = BIG ? rem : 64'hCCCCCCCCCCCCCCCC; |
`MODSU: o[63:0] = BIG ? rem : 64'hCCCCCCCCCCCCCCCC; |
`MOD: o[63:0] = BIG ? rem : 64'hCCCCCCCCCCCCCCCC; |
`LEAX: |
begin |
o[63:0] = BIG ? a + (b << instr[22:21]) : 64'hCCCCCCCCEEEEEEEE; |
988,7 → 993,8
`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); |
`MULU: exc <= prod[127:64] != 64'd0 && excen[3] ? `FLT_OFL : `FLT_NONE; |
`DIVMOD,`DIVMODSU,`DIVMODU: 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; |
default: exc <= `FLT_NONE; |
endcase |
`MULI: exc <= prod[63] ? (prod[127:64] != 64'hFFFFFFFFFFFFFFFF & excen[3] ? `FLT_OFL : `FLT_NONE): |
/rtl/common/FT64_config.vh
22,7 → 22,7
// |
// ============================================================================ |
// |
`define SIM 1'b1 |
//`define SIM 1'b1 |
//`define SUPPORT_SMT 1'b1 |
//`define DEBUG_LOGIC 1'b1 |
|
/rtl/common/FT64_defines.vh
145,27 → 145,16
`define NOR 6'h0D |
`define XNOR 6'h0E |
`define SHIFT31 6'h0F |
`define LHX 6'h10 |
`define LHUX 6'h11 |
`define LWX 6'h12 |
`define LBX 6'h13 |
`define SHX 6'h14 |
`define SBX 6'h15 |
`define SWX 6'h16 |
`define SWCX 6'h17 |
`define MODU 6'h14 |
`define MODSU 6'h15 |
`define MOD 6'h16 |
`define LEAX 6'h18 |
`define MUX 6'h1B |
`define LWRX 6'h1D |
`define CACHEX 6'h1E |
`define SHIFT63 6'h1F |
`define LCX 6'h20 |
`define LCUX 6'h21 |
`define MOV 6'h22 |
`define LBUX 6'h23 |
`define SCX 6'h24 |
`define CASX 6'h25 |
`define LVWS 6'h26 |
`define SVWS 6'h27 |
`define MOV 6'b01001? |
`define MULUH 6'h24 |
`define MULSUH 6'h25 |
`define MULH 6'h26 |
`define SLE 6'h28 |
`define SLEU 6'h29 |
`define CMOVEZ 6'h28 // 48 bit op |
179,14 → 168,12
`define RTI 6'h32 |
`define RTE 6'h32 |
`define VMOV 6'h33 |
`define LVX 6'h36 |
`define SVX 6'h37 |
`define MULU 6'h38 |
`define MULSU 6'h39 |
`define MUL 6'h3A |
`define DIVMODU 6'h3C |
`define DIVMODSU 6'h3D |
`define DIVMOD 6'h3E |
`define DIVU 6'h3C |
`define DIVSU 6'h3D |
`define DIV 6'h3E |
`define SHIFTH 6'h3F |
// Root Level Ops |
`define ADDI 6'h04 |
204,6 → 191,32
`define LB 6'h13 |
`define SB 6'h15 |
`define MEMNDX 6'h16 |
`define LVBX 6'h00 |
`define LVBUX 6'h01 |
`define LVCX 6'h02 |
`define LVCUX 6'h03 |
`define LVHX 6'h04 |
`define LVHUX 6'h05 |
`define LVWX 6'h06 |
`define LHX 6'h10 |
`define LHUX 6'h11 |
`define LWX 6'h12 |
`define LBX 6'h13 |
`define SHX 6'h14 |
`define SBX 6'h15 |
`define SWX 6'h16 |
`define SWCX 6'h17 |
`define LWRX 6'h1D |
`define CACHEX 6'h1E |
`define LCX 6'h20 |
`define LCUX 6'h21 |
`define LBUX 6'h23 |
`define SCX 6'h24 |
`define CASX 6'h25 |
`define LVWS 6'h26 |
`define SVWS 6'h27 |
`define LVX 6'h36 |
`define SVX 6'h37 |
`define SWC 6'h17 |
`define JAL 6'h18 |
`define CALL 6'h19 |
422,13 → 435,14
|
`define IB_CONST 127:64 |
`define IB_LN 63:61 |
`define IB_RT 54:50 |
`define IB_RC 49:45 |
`define IB_RB 44:40 |
`define IB_RA 39:35 |
`define IB_A3V 34 |
`define IB_A2V 33 |
`define IB_A1V 32 |
`define IB_RT 59:55 |
`define IB_RC 54:50 |
`define IB_RB 49:45 |
`define IB_RA 44:40 |
`define IB_ODDBALL 37 |
`define IB_STORE 36 |
`define IB_MEMSZ 35:33 |
`define IB_LOADV 32 |
`define IB_IMM 31 |
`define IB_MEM 30 |
`define IB_BT 28 |
/rtl/common/FT64_idecoder.v
40,6 → 40,11
|
parameter TRUE = 1'b1; |
parameter FALSE = 1'b0; |
// Memory access sizes |
parameter byt = 3'd0; |
parameter wyde = 3'd1; |
parameter tetra = 3'd2; |
parameter octa = 3'd3; |
|
// Really IsPredictableBranch |
// Does not include BccR's |
65,14 → 70,15
reg IsALU; |
always @* |
case(instr[`INSTRUCTION_OP]) |
`R2: if (instr[`INSTRUCTION_L2]==2'b00) |
case(instr[`INSTRUCTION_S2]) |
`VMOV: IsALU = TRUE; |
`RTI: IsALU = FALSE; |
default: IsALU = TRUE; |
endcase |
else |
IsALU = TRUE; |
`R2: |
if (instr[`INSTRUCTION_L2]==2'b00) |
case(instr[`INSTRUCTION_S2]) |
`VMOV: IsALU = TRUE; |
`RTI: IsALU = FALSE; |
default: IsALU = TRUE; |
endcase |
else |
IsALU = TRUE; |
`BRK: IsALU = FALSE; |
`Bcc: IsALU = FALSE; |
`BBc: IsALU = FALSE; |
83,15 → 89,15
`CALL: IsALU = FALSE; |
`RET: IsALU = FALSE; |
`FVECTOR: |
case(instr[`INSTRUCTION_S2]) |
`VSHL,`VSHR,`VASR: IsALU = TRUE; |
default: IsALU = FALSE; // Integer |
endcase |
case(instr[`INSTRUCTION_S2]) |
`VSHL,`VSHR,`VASR: IsALU = TRUE; |
default: IsALU = FALSE; // Integer |
endcase |
`IVECTOR: |
case(instr[`INSTRUCTION_S2]) |
`VSHL,`VSHR,`VASR: IsALU = TRUE; |
default: IsALU = TRUE; // Integer |
endcase |
case(instr[`INSTRUCTION_S2]) |
`VSHL,`VSHR,`VASR: IsALU = TRUE; |
default: IsALU = TRUE; // Integer |
endcase |
`FLOAT: IsALU = FALSE; |
default: IsALU = TRUE; |
endcase |
107,7 → 113,9
`SHIFTR,`SHIFT31,`SHIFT63: |
IsAlu0Only = TRUE; |
`MULU,`MULSU,`MUL, |
`DIVMODU,`DIVMODSU,`DIVMOD: IsAlu0Only = TRUE; |
`MULUH,`MULSUH,`MULH, |
`MODU,`MODSU,`MOD: IsAlu0Only = TRUE; |
`DIVU,`DIVSU,`DIV: IsAlu0Only = TRUE; |
`MIN,`MAX: IsAlu0Only = TRUE; |
default: IsAlu0Only = FALSE; |
endcase |
216,7 → 224,10
fnCanException = `TRUE; |
`R2: |
case(isn[`INSTRUCTION_S2]) |
`ADD,`SUB,`MUL,`DIVMOD,`MULSU,`DIVMODSU: fnCanException = TRUE; |
`ADD,`SUB,`MUL, |
`DIV,`MULSU,`DIVSU, |
`MOD,`MODSU: |
fnCanException = TRUE; |
`RTI: fnCanException = TRUE; |
default: fnCanException = FALSE; |
endcase |
241,19 → 252,25
case(isn[`INSTRUCTION_OP]) |
`MEMNDX: |
if (isn[`INSTRUCTION_L2]==2'b00) |
case(isn[`INSTRUCTION_S2]) |
`LBX: IsLoad = TRUE; |
`LBUX: IsLoad = TRUE; |
`LCX: IsLoad = TRUE; |
`LCUX: IsLoad = TRUE; |
`LHX: IsLoad = TRUE; |
`LHUX: IsLoad = TRUE; |
`LWX: IsLoad = TRUE; |
`LWRX: IsLoad = TRUE; |
`LVX: IsLoad = TRUE; |
`LVx: IsLoad = TRUE; |
default: IsLoad = FALSE; |
endcase |
case(isn[`INSTRUCTION_S2]) |
`LBX: IsLoad = TRUE; |
`LBUX: IsLoad = TRUE; |
`LCX: IsLoad = TRUE; |
`LCUX: IsLoad = TRUE; |
`LHX: IsLoad = TRUE; |
`LHUX: IsLoad = TRUE; |
`LWX: IsLoad = TRUE; |
`LVBX: IsLoad = TRUE; |
`LVBUX: IsLoad = TRUE; |
`LVCX: IsLoad = TRUE; |
`LVCUX: IsLoad = TRUE; |
`LVHX: IsLoad = TRUE; |
`LVHUX: IsLoad = TRUE; |
`LVWX: IsLoad = TRUE; |
`LWRX: IsLoad = TRUE; |
`LVX: IsLoad = TRUE; |
default: IsLoad = FALSE; |
endcase |
else |
IsLoad = FALSE; |
`LB: IsLoad = TRUE; |
267,6 → 284,59
endcase |
endfunction |
|
function IsVolatileLoad; |
input [47:0] isn; |
case(isn[`INSTRUCTION_OP]) |
`MEMNDX: |
if (isn[`INSTRUCTION_L2]==2'b00) |
case(isn[`INSTRUCTION_S2]) |
`LWRX: IsVolatileLoad = TRUE; |
`LVBX: IsVolatileLoad = TRUE; |
`LVBUX: IsVolatileLoad = TRUE; |
`LVCX: IsVolatileLoad = TRUE; |
`LVCUX: IsVolatileLoad = TRUE; |
`LVHX: IsVolatileLoad = TRUE; |
`LVHUX: IsVolatileLoad = TRUE; |
`LVWX: IsVolatileLoad = TRUE; |
default: IsVolatileLoad = FALSE; |
endcase |
else |
IsVolatileLoad = FALSE; |
`LWR: IsVolatileLoad = TRUE; |
`LVx: IsVolatileLoad = TRUE; |
default: IsVolatileLoad = FALSE; |
endcase |
endfunction |
|
function IsStore; |
input [47:0] isn; |
case(isn[`INSTRUCTION_OP]) |
`MEMNDX: |
if (isn[`INSTRUCTION_L2]==2'b00) |
case(isn[`INSTRUCTION_S2]) |
`SBX: IsStore = TRUE; |
`SCX: IsStore = TRUE; |
`SHX: IsStore = TRUE; |
`SWX: IsStore = TRUE; |
`SWCX: IsStore = TRUE; |
`SVX: IsStore = TRUE; |
`CASX: IsStore = TRUE; |
`INC: IsStore = TRUE; |
default: IsStore = FALSE; |
endcase |
else |
IsStore = FALSE; |
`SB: IsStore = TRUE; |
`Sx: IsStore = TRUE; |
`SWC: IsStore = TRUE; |
`INC: IsStore = TRUE; |
`SV: IsStore = TRUE; |
`CAS: IsStore = TRUE; |
`AMO: IsStore = TRUE; |
default: IsStore = FALSE; |
endcase |
endfunction |
|
function [0:0] IsMem; |
input [47:0] isn; |
case(isn[`INSTRUCTION_OP]) |
296,6 → 366,56
endcase |
endfunction |
|
function [2:0] MemSize; |
input [47:0] isn; |
case(isn[`INSTRUCTION_OP]) |
`MEMNDX: |
if (isn[`INSTRUCTION_L2]==2'b00) |
case(isn[`INSTRUCTION_S2]) |
`LVBX,`LVBUX: MemSize = byt; |
`LBX,`LBUX,`SBX: MemSize = byt; |
`LVCX,`LVCUX: MemSize = wyde; |
`LCX,`LCUX,`SCX: MemSize = wyde; |
`LVHX,`LVHUX: MemSize = tetra; |
`LHX,`SHX: MemSize = tetra; |
`LHUX: MemSize = tetra; |
`LVWX: MemSize = octa; |
`LWX,`SWX: MemSize = octa; |
`LWRX,`SWCX: MemSize = octa; |
`LVX,`SVX: MemSize = octa; |
`LVx: |
case(isn[25:23]) |
3'd0,3'd1: MemSize = byt; |
3'd2,3'd3: MemSize = wyde; |
3'd4,3'd5: MemSize = tetra; |
default: MemSize = octa; |
endcase |
default: MemSize = octa; |
endcase |
else |
MemSize = octa; |
`LB,`LBU,`SB: MemSize = byt; |
`Lx,`LxU,`Sx,`LVx: |
casez(isn[20:18]) |
3'b100: MemSize = octa; |
3'b?10: MemSize = tetra; |
3'b??1: MemSize = wyde; |
default: MemSize = octa; |
endcase |
`LWR,`SWC: MemSize = octa; |
`LV,`SV: MemSize = octa; |
`AMO: |
case(isn[23:21]) |
3'd0: MemSize = byt; |
3'd1: MemSize = wyde; |
3'd2: MemSize = tetra; |
3'd3: MemSize = octa; |
default: MemSize = octa; |
endcase |
default: MemSize = octa; |
endcase |
endfunction |
|
function IsCAS; |
input [47:0] isn; |
case(isn[`INSTRUCTION_OP]) |
472,6 → 592,34
endcase |
endfunction |
|
function IsOddball; |
input [47:0] instr; |
//if (|iqentry_exc[head]) |
// IsOddball = TRUE; |
//else |
case(instr[`INSTRUCTION_OP]) |
`BRK: IsOddball = TRUE; |
`IVECTOR: |
case(instr[`INSTRUCTION_S2]) |
`VSxx: IsOddball = TRUE; |
default: IsOddball = FALSE; |
endcase |
`RR: |
case(instr[`INSTRUCTION_S2]) |
`VMOV: IsOddball = TRUE; |
`SEI,`RTI: IsOddball = TRUE; |
default: IsOddball = FALSE; |
endcase |
`MEMNDX: |
case(instr[`INSTRUCTION_S2]) |
`CACHEX: IsOddball = TRUE; |
default: IsOddball = FALSE; |
endcase |
`CSRRW,`REX,`CACHE,`FLOAT: IsOddball = TRUE; |
default: IsOddball = FALSE; |
endcase |
endfunction |
|
function IsRFW; |
input [47:0] isn; |
casez(isn[`INSTRUCTION_OP]) |
479,49 → 627,62
`FVECTOR: IsRFW = TRUE; |
`R2: |
if (isn[`INSTRUCTION_L2]==2'b00) |
case(isn[`INSTRUCTION_S2]) |
`R1: IsRFW = TRUE; |
`ADD: IsRFW = TRUE; |
`SUB: IsRFW = TRUE; |
`SLT: IsRFW = TRUE; |
`SLTU: IsRFW = TRUE; |
`SLE: IsRFW = TRUE; |
`SLEU: IsRFW = TRUE; |
`AND: IsRFW = TRUE; |
`OR: IsRFW = TRUE; |
`XOR: IsRFW = TRUE; |
`MULU: IsRFW = TRUE; |
`MULSU: IsRFW = TRUE; |
`MUL: IsRFW = TRUE; |
`DIVMODU: IsRFW = TRUE; |
`DIVMODSU: IsRFW = TRUE; |
`DIVMOD:IsRFW = TRUE; |
`MOV: IsRFW = TRUE; |
`VMOV: IsRFW = TRUE; |
`SHIFTR,`SHIFT31,`SHIFT63: |
IsRFW = TRUE; |
`MIN,`MAX: IsRFW = TRUE; |
`SEI: IsRFW = TRUE; |
default: IsRFW = FALSE; |
endcase |
case(isn[`INSTRUCTION_S2]) |
`R1: IsRFW = TRUE; |
`ADD: IsRFW = TRUE; |
`SUB: IsRFW = TRUE; |
`SLT: IsRFW = TRUE; |
`SLTU: IsRFW = TRUE; |
`SLE: IsRFW = TRUE; |
`SLEU: IsRFW = TRUE; |
`AND: IsRFW = TRUE; |
`OR: IsRFW = TRUE; |
`XOR: IsRFW = TRUE; |
`MULU: IsRFW = TRUE; |
`MULSU: IsRFW = TRUE; |
`MUL: IsRFW = TRUE; |
`MULUH: IsRFW = TRUE; |
`MULSUH: IsRFW = TRUE; |
`MULH: IsRFW = TRUE; |
`DIVU: IsRFW = TRUE; |
`DIVSU: IsRFW = TRUE; |
`DIV:IsRFW = TRUE; |
`MODU: IsRFW = TRUE; |
`MODSU: IsRFW = TRUE; |
`MOD:IsRFW = TRUE; |
`MOV: IsRFW = TRUE; |
`VMOV: IsRFW = TRUE; |
`SHIFTR,`SHIFT31,`SHIFT63: |
IsRFW = TRUE; |
`MIN,`MAX: IsRFW = TRUE; |
`SEI: IsRFW = TRUE; |
default: IsRFW = FALSE; |
endcase |
else |
IsRFW = FALSE; |
`MEMNDX: |
if (isn[`INSTRUCTION_L2]==2'b00) |
case(isn[`INSTRUCTION_S2]) |
`LBX: IsRFW = TRUE; |
`LBUX: IsRFW = TRUE; |
`LCX: IsRFW = TRUE; |
`LCUX: IsRFW = TRUE; |
`LHX: IsRFW = TRUE; |
`LHUX: IsRFW = TRUE; |
`LWX: IsRFW = TRUE; |
`LWRX: IsRFW = TRUE; |
`LVX: IsRFW = TRUE; |
`LVx: IsRFW = TRUE; |
`CASX: IsRFW = TRUE; |
default: IsRFW = FALSE; |
endcase |
case(isn[`INSTRUCTION_S2]) |
`LBX: IsRFW = TRUE; |
`LBUX: IsRFW = TRUE; |
`LCX: IsRFW = TRUE; |
`LCUX: IsRFW = TRUE; |
`LHX: IsRFW = TRUE; |
`LHUX: IsRFW = TRUE; |
`LWX: IsRFW = TRUE; |
`LVBX: IsRFW = TRUE; |
`LVBUX: IsRFW = TRUE; |
`LVCX: IsRFW = TRUE; |
`LVCUX: IsRFW = TRUE; |
`LVHX: IsRFW = TRUE; |
`LVHUX: IsRFW = TRUE; |
`LVWX: IsRFW = TRUE; |
`LWX: IsRFW = TRUE; |
`LWRX: IsRFW = TRUE; |
`LVX: IsRFW = TRUE; |
`CASX: IsRFW = TRUE; |
default: IsRFW = FALSE; |
endcase |
else |
IsRFW = FALSE; |
`BBc: |
584,8 → 745,10
`ADD,`SUB, |
`AND,`OR,`XOR, |
`NAND,`NOR,`XNOR, |
`DIVMOD,`DIVMODU,`DIVMODSU, |
`MUL,`MULU,`MULSU: |
`DIV,`DIVU,`DIVSU, |
`MOD,`MODU,`MODSU, |
`MUL,`MULU,`MULSU, |
`MULH,`MULUH,`MULSUH: |
case(isn[25:23]) |
3'b000: fnWe = 8'h01; |
3'b001: fnWe = 8'h03; |
762,9 → 925,9
// bus[`IB_RC] <= fnRc(instr,ven,thrd) | {thrd,7'b0}; |
// bus[`IB_RA] <= fnRa(instr,ven,vl,thrd) | {thrd,7'b0}; |
bus[`IB_IMM] <= HasConst(instr); |
bus[`IB_A3V] <= Source3Valid(instr); |
bus[`IB_A2V] <= Source2Valid(instr); |
bus[`IB_A1V] <= Source1Valid(instr); |
// bus[`IB_A3V] <= Source3Valid(instr); |
// bus[`IB_A2V] <= Source2Valid(instr); |
// bus[`IB_A1V] <= Source1Valid(instr); |
bus[`IB_BT] <= (IsBranch(instr) && predict_taken); |
bus[`IB_ALU] <= IsALU; |
bus[`IB_ALU0] <= IsAlu0Only(instr); |
771,8 → 934,12
bus[`IB_FPU] <= IsFPU(instr); |
bus[`IB_FC] <= IsFlowCtrl; |
bus[`IB_CANEX] <= fnCanException(instr); |
bus[`IB_LOADV] <= IsVolatileLoad(instr); |
bus[`IB_LOAD] <= IsLoad(instr); |
bus[`IB_PRELOAD] <= IsLoad(instr) && Rt==5'd0; |
bus[`IB_STORE] <= IsStore(instr); |
bus[`IB_ODDBALL] <= IsOddball(instr); |
bus[`IB_MEMSZ] <= MemSize(instr); |
bus[`IB_MEM] <= IsMem(instr); |
bus[`IB_MEMNDX] <= IsMemNdx(instr); |
bus[`IB_RMW] <= IsCAS(instr) || IsAMO(instr) || IsInc(instr); |
802,14 → 969,15
|
always @* |
casez(instr[`INSTRUCTION_OP]) |
`R2: if (instr[`INSTRUCTION_L2]==2'b00) |
case(instr[`INSTRUCTION_S2]) |
`VMOV: IsALU = TRUE; |
`RTI: IsALU = FALSE; |
default: IsALU = TRUE; |
endcase |
else |
IsALU = TRUE; |
`R2: |
if (instr[`INSTRUCTION_L2]==2'b00) |
case(instr[`INSTRUCTION_S2]) |
`VMOV: IsALU = TRUE; |
`RTI: IsALU = FALSE; |
default: IsALU = TRUE; |
endcase |
else |
IsALU = TRUE; |
`BRK: IsALU = FALSE; |
`Bcc: IsALU = FALSE; |
`BBc: IsALU = FALSE; |
820,15 → 988,15
`CALL: IsALU = FALSE; |
`RET: IsALU = FALSE; |
`FVECTOR: |
case(instr[`INSTRUCTION_S2]) |
`VSHL,`VSHR,`VASR: IsALU = TRUE; |
default: IsALU = FALSE; // Integer |
endcase |
case(instr[`INSTRUCTION_S2]) |
`VSHL,`VSHR,`VASR: IsALU = TRUE; |
default: IsALU = FALSE; // Integer |
endcase |
`IVECTOR: |
case(instr[`INSTRUCTION_S2]) |
`VSHL,`VSHR,`VASR: IsALU = TRUE; |
default: IsALU = TRUE; // Integer |
endcase |
case(instr[`INSTRUCTION_S2]) |
`VSHL,`VSHR,`VASR: IsALU = TRUE; |
default: IsALU = TRUE; // Integer |
endcase |
`FLOAT: IsALU = FALSE; |
default: IsALU = TRUE; |
endcase |
/rtl/common/FT64_mpu.v
188,26 → 188,26
|
FT64_mmu ummu1 |
( |
.rst_i(rst_i), |
.clk_i(clk_i), |
.ol_i(ol), |
.pcr_i(pcr), |
.pcr2_i(pcr2), |
.mapen_i(pcr[31]), |
.s_ex_i(icl), |
.s_cyc_i(cyc), |
.s_stb_i(stb), |
.s_ack_o(mmu_ack), |
.s_wr_i(we_o), |
.s_adr_i(adr), |
.s_dat_i(dat_o[31:0]), |
.s_dat_o(mmu_dato), |
.cyc_o(cyc_o), |
.stb_o(stb_o), |
.pea_o(adr_o), |
.exv_o(exv), |
.rdv_o(rdv), |
.wrv_o(wrv) |
.rst_i(rst_i), |
.clk_i(clk_i), |
.ol_i(ol), |
.pcr_i(pcr), |
.pcr2_i(pcr2), |
.mapen_i(pcr[31]), |
.s_ex_i(icl), |
.s_cyc_i(cyc), |
.s_stb_i(stb), |
.s_ack_o(mmu_ack), |
.s_wr_i(we_o), |
.s_adr_i(adr), |
.s_dat_i(dat_o[31:0]), |
.s_dat_o(mmu_dato), |
.cyc_o(cyc_o), |
.stb_o(stb_o), |
.pea_o(adr_o), |
.exv_o(exv), |
.rdv_o(rdv), |
.wrv_o(wrv) |
); |
|
CardMemory ucrd1 |
/rtl/twoway/FT64.v
38,6 → 38,7
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// Approx. 100,000 LUTs. 160,000 LC's. |
// 38,000LUTs??? |
// ============================================================================ |
// |
`include "FT64_config.vh" |
114,11 → 115,12
parameter IQS_S3 = 2'd3; |
|
wire clk; |
BUFG uclkb1 |
( |
.I(clk_i), |
.O(clk) |
); |
//BUFG uclkb1 |
//( |
// .I(clk_i), |
// .O(clk) |
//); |
assign clk = clk_i; |
|
wire dc_ack; |
wire acki = ack_i|dc_ack; |
492,11 → 494,15
reg [QENTRIES-1:0] iqentry_fpu; // floating point instruction |
reg [QENTRIES-1:0] iqentry_fc; // flow control instruction |
reg [QENTRIES-1:0] iqentry_canex = 8'h00; // true if it's an instruction that can exception |
reg [QENTRIES-1:0] iqentry_oddball = 8'h00; // writes to register file |
reg [QENTRIES-1:0] iqentry_load; // is a memory load instruction |
reg [QENTRIES-1:0] iqentry_loadv; // is a volatile memory load instruction |
reg [QENTRIES-1:0] iqentry_store; // is a memory store instruction |
reg [QENTRIES-1:0] iqentry_preload; // is a memory preload instruction |
reg [QENTRIES-1:0] iqentry_ldcmp; |
reg [QENTRIES-1:0] iqentry_mem; // touches memory: 1 if LW/SW |
reg [QENTRIES-1:0] iqentry_memndx; // indexed memory operation |
reg [2:0] iqentry_memsz [0:QENTRIES-1]; // size of memory op |
reg [QENTRIES-1:0] iqentry_rmw; // memory RMW op |
reg [QENTRIES-1:0] iqentry_memdb; |
reg [QENTRIES-1:0] iqentry_memsb; |
840,6 → 846,7
reg dram0_unc; |
reg [2:0] dram0_memsize; |
reg dram0_load; // is a load operation |
reg dram0_store; |
reg [1:0] dram0_ol; |
reg [63:0] dram1_data; |
reg [`ABITS] dram1_addr; |
853,6 → 860,7
reg dram1_unc; |
reg [2:0] dram1_memsize; |
reg dram1_load; |
reg dram1_store; |
reg [1:0] dram1_ol; |
reg [63:0] dram2_data; |
reg [`ABITS] dram2_addr; |
866,6 → 874,7
reg dram2_unc; |
reg [2:0] dram2_memsize; |
reg dram2_load; |
reg dram2_store; |
reg [1:0] dram2_ol; |
|
reg dramA_v; |
1126,15 → 1135,16
iqentry_instr[head1][`INSTRUCTION_OP]==`BRK || |
IsRTI(iqentry_instr[head1])); |
|
wire fcu_clk; |
`ifdef FCU_ENH |
wire fcu_clk; |
BUFGCE ufcuclk |
( |
.I(clk_i), |
.CE(fcu_available), |
.O(fcu_clk) |
); |
//BUFGCE ufcuclk |
//( |
// .I(clk_i), |
// .CE(fcu_available), |
// .O(fcu_clk) |
//); |
`endif |
assign fcu_clk = clk_i; |
|
`ifdef FCU_ENH |
FT64_BTB ubtb1 |
1680,11 → 1690,11
`VSxx,`VSxxU,`VSxxS,`VSxxSU: fnRa = {vqei,1'b1,isn[`INSTRUCTION_RA]}; |
default: fnRa = {vqei,1'b1,isn[`INSTRUCTION_RA]}; |
endcase |
`R2: case(isn[`INSTRUCTION_S2]) |
`R2: casez(isn[`INSTRUCTION_S2]) |
`MOV: |
case(isn[25:23]) |
3'd0: fnRa = {rgs[thrd],1'b0,isn[`INSTRUCTION_RA]}; |
3'd1: fnRa = {isn[22:18],1'b0,isn[`INSTRUCTION_RA]}; |
3'd1: fnRa = {isn[26],isn[22:18],1'b0,isn[`INSTRUCTION_RA]}; |
3'd2: fnRa = {rgs[thrd],1'b0,isn[`INSTRUCTION_RA]}; |
3'd3: fnRa = {rs_stack[thrd][5:0],1'b0,isn[`INSTRUCTION_RA]}; |
3'd4: fnRa = {rgs[thrd],1'b0,isn[`INSTRUCTION_RA]}; |
1786,10 → 1796,10
default: fnRt = {vqei,1'b1,isn[`INSTRUCTION_RC]}; |
endcase |
|
`R2: case(isn[`INSTRUCTION_S2]) |
`R2: casez(isn[`INSTRUCTION_S2]) |
`MOV: |
case(isn[25:23]) |
3'd0: fnRt = {isn[22:18],1'b0,isn[`INSTRUCTION_RB]}; |
3'd0: fnRt = {isn[26],isn[22:18],1'b0,isn[`INSTRUCTION_RB]}; |
3'd1: fnRt = {rgs[thrd],1'b0,isn[`INSTRUCTION_RB]}; |
3'd2: fnRt = {rs_stack[thrd][5:0],1'b0,isn[`INSTRUCTION_RB]}; |
3'd3: fnRt = {rgs[thrd],1'b0,isn[`INSTRUCTION_RB]}; |
1882,25 → 1892,26
`VSxx,`VSxxU,`VSxxS,`VSxxSU: fnRa = {vqei,1'b1,isn[`INSTRUCTION_RA]}; |
default: fnRa = {vqei,1'b1,isn[`INSTRUCTION_RA]}; |
endcase |
`RR: case(isn[`INSTRUCTION_S2]) |
`MOV: |
case(isn[25:23]) |
3'd0: fnRa = {rgs,1'b0,isn[`INSTRUCTION_RA]}; |
3'd1: fnRa = {isn[22:18],1'b0,isn[`INSTRUCTION_RA]}; |
3'd2: fnRa = {rgs,1'b0,isn[`INSTRUCTION_RA]}; |
3'd3: fnRa = {rs_stack[5:0],1'b0,isn[`INSTRUCTION_RA]}; |
3'd4: fnRa = {rgs,1'b0,isn[`INSTRUCTION_RA]}; |
3'd5: fnRa = {fp1_rgs,1'b0,isn[`INSTRUCTION_RA]}; |
3'd6: fnRa = {fp1_rgs,1'b0,isn[`INSTRUCTION_RA]}; |
default:fnRa = {rgs,1'b0,isn[`INSTRUCTION_RA]}; |
endcase |
`VMOV: |
case (isn[`INSTRUCTION_S1]) |
5'h0: fnRa = {rgs,1'b0,isn[`INSTRUCTION_RA]}; |
5'h1: fnRa = {6'h3F,1'b1,isn[`INSTRUCTION_RA]}; |
endcase |
default: fnRa = {rgs,1'b0,isn[`INSTRUCTION_RA]}; |
endcase |
`R2: |
casez(isn[`INSTRUCTION_S2]) |
`MOV: |
case(isn[25:23]) |
3'd0: fnRa = {rgs,1'b0,isn[`INSTRUCTION_RA]}; |
3'd1: fnRa = {isn[26],isn[22:18],1'b0,isn[`INSTRUCTION_RA]}; |
3'd2: fnRa = {rgs,1'b0,isn[`INSTRUCTION_RA]}; |
3'd3: fnRa = {rs_stack[5:0],1'b0,isn[`INSTRUCTION_RA]}; |
3'd4: fnRa = {rgs,1'b0,isn[`INSTRUCTION_RA]}; |
3'd5: fnRa = {fp1_rgs,1'b0,isn[`INSTRUCTION_RA]}; |
3'd6: fnRa = {fp1_rgs,1'b0,isn[`INSTRUCTION_RA]}; |
default:fnRa = {rgs,1'b0,isn[`INSTRUCTION_RA]}; |
endcase |
`VMOV: |
case (isn[`INSTRUCTION_S1]) |
5'h0: fnRa = {rgs,1'b0,isn[`INSTRUCTION_RA]}; |
5'h1: fnRa = {6'h3F,1'b1,isn[`INSTRUCTION_RA]}; |
endcase |
default: fnRa = {rgs,1'b0,isn[`INSTRUCTION_RA]}; |
endcase |
`FLOAT: fnRa = {fp1_rgs,1'b0,isn[`INSTRUCTION_RA]}; |
default: fnRa = {rgs,1'b0,isn[`INSTRUCTION_RA]}; |
endcase |
2006,46 → 2017,47
default: fnRt = {vqei,1'b1,isn[`INSTRUCTION_RC]}; |
endcase |
|
`R2: case(isn[`INSTRUCTION_S2]) |
`MOV: |
case(isn[25:23]) |
3'd0: fnRt = {isn[22:18],1'b0,isn[`INSTRUCTION_RB]}; |
3'd1: fnRt = {rgs,1'b0,isn[`INSTRUCTION_RB]}; |
3'd2: fnRt = {rs_stack[5:0],1'b0,isn[`INSTRUCTION_RB]}; |
3'd3: fnRt = {rgs,1'b0,isn[`INSTRUCTION_RB]}; |
3'd4: fnRt = {fp1_rgs,1'b0,isn[`INSTRUCTION_RB]}; |
3'd5: fnRt = {rgs,1'b0,isn[`INSTRUCTION_RB]}; |
3'd6: fnRt = {fp1_rgs,1'b0,isn[`INSTRUCTION_RB]}; |
default:fnRt = {rgs,1'b0,isn[`INSTRUCTION_RB]}; |
endcase |
`VMOV: |
case (isn[`INSTRUCTION_S1]) |
5'h0: fnRt = {6'h3F,1'b1,isn[`INSTRUCTION_RB]}; |
5'h1: fnRt = {rgs,1'b0,isn[`INSTRUCTION_RB]}; |
default: fnRt = 12'h000; |
endcase |
`R1: |
case(isn[22:18]) |
`CNTLO,`CNTLZ,`CNTPOP,`ABS,`NOT: |
fnRt = {rgs,1'b0,isn[`INSTRUCTION_RB]}; |
`MEMDB,`MEMSB,`SYNC: |
fnRt = 12'd0; |
default: fnRt = 12'd0; |
endcase |
`CMOVEZ: fnRt = {rgs,1'b0,isn[`INSTRUCTION_S1]}; |
`CMOVNZ: fnRt = {rgs,1'b0,isn[`INSTRUCTION_S1]}; |
`MUX: fnRt = {rgs,1'b0,isn[`INSTRUCTION_S1]}; |
`MIN: fnRt = {rgs,1'b0,isn[`INSTRUCTION_S1]}; |
`MAX: fnRt = {rgs,1'b0,isn[`INSTRUCTION_S1]}; |
`LVX: fnRt = {vqei,1'b1,isn[20:16]}; |
`SHIFTR: fnRt = {rgs,1'b0,isn[`INSTRUCTION_RC]}; |
`SHIFT31,`SHIFT63: |
fnRt = {rgs,1'b0,isn[`INSTRUCTION_RB]}; |
`SEI: fnRt = {rgs,1'b0,isn[`INSTRUCTION_RB]}; |
`WAIT,`RTI,`CHK: |
fnRt = 12'd0; |
default: fnRt = {rgs,1'b0,isn[`INSTRUCTION_RC]}; |
endcase |
`R2: |
casez(isn[`INSTRUCTION_S2]) |
`MOV: |
case(isn[25:23]) |
3'd0: fnRt = {isn[26],isn[22:18],1'b0,isn[`INSTRUCTION_RB]}; |
3'd1: fnRt = {rgs,1'b0,isn[`INSTRUCTION_RB]}; |
3'd2: fnRt = {rs_stack[5:0],1'b0,isn[`INSTRUCTION_RB]}; |
3'd3: fnRt = {rgs,1'b0,isn[`INSTRUCTION_RB]}; |
3'd4: fnRt = {fp1_rgs,1'b0,isn[`INSTRUCTION_RB]}; |
3'd5: fnRt = {rgs,1'b0,isn[`INSTRUCTION_RB]}; |
3'd6: fnRt = {fp1_rgs,1'b0,isn[`INSTRUCTION_RB]}; |
default:fnRt = {rgs,1'b0,isn[`INSTRUCTION_RB]}; |
endcase |
`VMOV: |
case (isn[`INSTRUCTION_S1]) |
5'h0: fnRt = {6'h3F,1'b1,isn[`INSTRUCTION_RB]}; |
5'h1: fnRt = {rgs,1'b0,isn[`INSTRUCTION_RB]}; |
default: fnRt = 12'h000; |
endcase |
`R1: |
case(isn[22:18]) |
`CNTLO,`CNTLZ,`CNTPOP,`ABS,`NOT: |
fnRt = {rgs,1'b0,isn[`INSTRUCTION_RB]}; |
`MEMDB,`MEMSB,`SYNC: |
fnRt = 12'd0; |
default: fnRt = 12'd0; |
endcase |
`CMOVEZ: fnRt = {rgs,1'b0,isn[`INSTRUCTION_S1]}; |
`CMOVNZ: fnRt = {rgs,1'b0,isn[`INSTRUCTION_S1]}; |
`MUX: fnRt = {rgs,1'b0,isn[`INSTRUCTION_S1]}; |
`MIN: fnRt = {rgs,1'b0,isn[`INSTRUCTION_S1]}; |
`MAX: fnRt = {rgs,1'b0,isn[`INSTRUCTION_S1]}; |
`LVX: fnRt = {vqei,1'b1,isn[20:16]}; |
`SHIFTR: fnRt = {rgs,1'b0,isn[`INSTRUCTION_RC]}; |
`SHIFT31,`SHIFT63: |
fnRt = {rgs,1'b0,isn[`INSTRUCTION_RB]}; |
`SEI: fnRt = {rgs,1'b0,isn[`INSTRUCTION_RB]}; |
`WAIT,`RTI,`CHK: |
fnRt = 12'd0; |
default: fnRt = {rgs,1'b0,isn[`INSTRUCTION_RC]}; |
endcase |
`MEMNDX: |
case(isn[`INSTRUCTION_S2]) |
`SBX,`SCX,`SHX,`SWX,`SWCX,`CACHEX: |
2107,8 → 2119,10
`ADD,`SUB, |
`AND,`OR,`XOR, |
`NAND,`NOR,`XNOR, |
`DIVMOD,`DIVMODU,`DIVMODSU, |
`MUL,`MULU,`MULSU: |
`DIV,`DIVU,`DIVSU, |
`MOD,`MODU,`MODSU, |
`MUL,`MULU,`MULSU, |
`MULH,`MULUH,`MULSUH: |
case(isn[25:23]) |
3'b000: fnWe = 8'h01; |
3'b001: fnWe = 8'h03; |
2410,19 → 2424,26
case(isn[`INSTRUCTION_OP]) |
`MEMNDX: |
if (isn[`INSTRUCTION_L2]==2'b00) |
case(isn[`INSTRUCTION_S2]) |
`LBX: IsLoad = TRUE; |
`LBUX: IsLoad = TRUE; |
`LCX: IsLoad = TRUE; |
`LCUX: IsLoad = TRUE; |
`LHX: IsLoad = TRUE; |
`LHUX: IsLoad = TRUE; |
`LWX: IsLoad = TRUE; |
`LWRX: IsLoad = TRUE; |
`LVX: IsLoad = TRUE; |
`LVx: IsLoad = TRUE; |
default: IsLoad = FALSE; |
endcase |
case(isn[`INSTRUCTION_S2]) |
`LBX: IsLoad = TRUE; |
`LBUX: IsLoad = TRUE; |
`LCX: IsLoad = TRUE; |
`LCUX: IsLoad = TRUE; |
`LHX: IsLoad = TRUE; |
`LHUX: IsLoad = TRUE; |
`LWX: IsLoad = TRUE; |
`LVBX: IsLoad = TRUE; |
`LVBUX: IsLoad = TRUE; |
`LVCX: IsLoad = TRUE; |
`LVCUX: IsLoad = TRUE; |
`LVHX: IsLoad = TRUE; |
`LVHUX: IsLoad = TRUE; |
`LVWX: IsLoad = TRUE; |
`LWRX: IsLoad = TRUE; |
`LVX: IsLoad = TRUE; |
`LVx: IsLoad = TRUE; |
default: IsLoad = FALSE; |
endcase |
else |
IsLoad = FALSE; |
`LB: IsLoad = TRUE; |
2436,106 → 2457,6
endcase |
endfunction |
|
function IsVolatileLoad; |
input [47:0] isn; |
case(isn[`INSTRUCTION_OP]) |
`MEMNDX: |
if (isn[`INSTRUCTION_L2]==2'b00) |
case(isn[`INSTRUCTION_S2]) |
`LWRX: IsVolatileLoad = TRUE; |
`LVx: IsVolatileLoad = TRUE; |
default: IsVolatileLoad = FALSE; |
endcase |
else |
IsVolatileLoad = FALSE; |
`LWR: IsVolatileLoad = TRUE; |
`LVx: IsVolatileLoad = TRUE; |
default: IsVolatileLoad = FALSE; |
endcase |
endfunction |
|
function [2:0] MemSize; |
input [47:0] isn; |
case(isn[`INSTRUCTION_OP]) |
`MEMNDX: |
if (isn[`INSTRUCTION_L2]==2'b00) |
case(isn[`INSTRUCTION_S2]) |
`LBX,`LBUX,`SBX: MemSize = byt; |
`LCX,`LCUX,`SCX: MemSize = wyde; |
`LHX,`SHX: MemSize = tetra; |
`LHUX: MemSize = tetra; |
`LWX,`SWX: MemSize = octa; |
`LWRX,`SWCX: MemSize = octa; |
`LVX,`SVX: MemSize = octa; |
`LVx: |
case(isn[25:23]) |
3'd0,3'd1: MemSize = byt; |
3'd2,3'd3: MemSize = wyde; |
3'd4,3'd5: MemSize = tetra; |
default: MemSize = octa; |
endcase |
default: MemSize = octa; |
endcase |
else |
MemSize = octa; |
`LB,`LBU,`SB: MemSize = byt; |
`Lx,`LxU,`Sx: |
casez(isn[20:18]) |
3'b100: MemSize = octa; |
3'b?10: MemSize = tetra; |
3'b??1: MemSize = wyde; |
default: MemSize = octa; |
endcase |
`LWR,`SWC: MemSize = octa; |
`LV,`SV: MemSize = octa; |
`AMO: |
case(isn[23:21]) |
3'd0: MemSize = byt; |
3'd1: MemSize = wyde; |
3'd2: MemSize = tetra; |
3'd3: MemSize = octa; |
default: MemSize = octa; |
endcase |
`LVx: |
case(isn[30:28]) |
3'd0,3'd1: MemSize = byt; |
3'd2,3'd3: MemSize = wyde; |
3'd4,3'd5: MemSize = tetra; |
default: MemSize = octa; |
endcase |
default: MemSize = octa; |
endcase |
endfunction |
|
function IsStore; |
input [47:0] isn; |
case(isn[`INSTRUCTION_OP]) |
`MEMNDX: |
if (isn[`INSTRUCTION_L2]==2'b00) |
case(isn[`INSTRUCTION_S2]) |
`SBX: IsStore = TRUE; |
`SCX: IsStore = TRUE; |
`SHX: IsStore = TRUE; |
`SWX: IsStore = TRUE; |
`SWCX: IsStore = TRUE; |
`SVX: IsStore = TRUE; |
`CASX: IsStore = TRUE; |
`INC: IsStore = TRUE; |
default: IsStore = FALSE; |
endcase |
else |
IsStore = FALSE; |
`SB: IsStore = TRUE; |
`Sx: IsStore = TRUE; |
`SWC: IsStore = TRUE; |
`INC: IsStore = TRUE; |
`SV: IsStore = TRUE; |
`CAS: IsStore = TRUE; |
`AMO: IsStore = TRUE; |
default: IsStore = FALSE; |
endcase |
endfunction |
|
function IsInc; |
input [47:0] isn; |
case(isn[`INSTRUCTION_OP]) |
2744,16 → 2665,6
endcase |
endfunction |
|
function IsSync; |
input [47:0] isn; |
IsSync = (isn[`INSTRUCTION_OP]==`R2 && isn[`INSTRUCTION_L2]==2'b00 && isn[`INSTRUCTION_S2]==`R1 && isn[22:18]==`SYNC); |
endfunction |
|
function IsFSync; |
input [47:0] isn; |
IsFSync = (isn[`INSTRUCTION_OP]==`FLOAT && isn[`INSTRUCTION_L2]==2'b00 && isn[`INSTRUCTION_S2]==`FSYNC); |
endfunction |
|
function IsMemsb; |
input [47:0] isn; |
IsMemsb = (isn[`INSTRUCTION_OP]==`RR && isn[`INSTRUCTION_L2]==2'b00 && isn[`INSTRUCTION_S2]==`R1 && isn[22:18]==`MEMSB); |
2807,9 → 2718,15
`MULU: IsRFW = TRUE; |
`MULSU: IsRFW = TRUE; |
`MUL: IsRFW = TRUE; |
`DIVMODU: IsRFW = TRUE; |
`DIVMODSU: IsRFW = TRUE; |
`DIVMOD:IsRFW = TRUE; |
`MULUH: IsRFW = TRUE; |
`MULSUH: IsRFW = TRUE; |
`MULH: IsRFW = TRUE; |
`DIVU: IsRFW = TRUE; |
`DIVSU: IsRFW = TRUE; |
`DIV:IsRFW = TRUE; |
`MODU: IsRFW = TRUE; |
`MODSU: IsRFW = TRUE; |
`MOD:IsRFW = TRUE; |
`MOV: IsRFW = TRUE; |
`VMOV: IsRFW = TRUE; |
`SHIFTR,`SHIFT31,`SHIFT63: |
2822,20 → 2739,26
IsRFW = FALSE; |
`MEMNDX: |
if (isn[`INSTRUCTION_L2]==2'b00) |
case(isn[`INSTRUCTION_S2]) |
`LBX: IsRFW = TRUE; |
`LBUX: IsRFW = TRUE; |
`LCX: IsRFW = TRUE; |
`LCUX: IsRFW = TRUE; |
`LHX: IsRFW = TRUE; |
`LHUX: IsRFW = TRUE; |
`LWX: IsRFW = TRUE; |
`LWRX: IsRFW = TRUE; |
`LVX: IsRFW = TRUE; |
`LVx: IsRFW = TRUE; |
`CASX: IsRFW = TRUE; |
default: IsRFW = FALSE; |
endcase |
case(isn[`INSTRUCTION_S2]) |
`LBX: IsRFW = TRUE; |
`LBUX: IsRFW = TRUE; |
`LCX: IsRFW = TRUE; |
`LCUX: IsRFW = TRUE; |
`LHX: IsRFW = TRUE; |
`LHUX: IsRFW = TRUE; |
`LWX: IsRFW = TRUE; |
`LVBX: IsRFW = TRUE; |
`LVBUX: IsRFW = TRUE; |
`LVCX: IsRFW = TRUE; |
`LVCUX: IsRFW = TRUE; |
`LVHX: IsRFW = TRUE; |
`LVHUX: IsRFW = TRUE; |
`LVWX: IsRFW = TRUE; |
`LWRX: IsRFW = TRUE; |
`LVX: IsRFW = TRUE; |
`CASX: IsRFW = TRUE; |
default: IsRFW = FALSE; |
endcase |
else |
IsRFW = FALSE; |
`BBc: |
2908,12 → 2831,13
function IsMul; |
input [47:0] isn; |
case(isn[`INSTRUCTION_OP]) |
`RR: |
`R2: |
if (isn[`INSTRUCTION_L2]==2'b00) |
case(isn[`INSTRUCTION_S2]) |
`MULU,`MULSU,`MUL: IsMul = TRUE; |
default: IsMul = FALSE; |
endcase |
case(isn[`INSTRUCTION_S2]) |
`MULU,`MULSU,`MUL: IsMul = TRUE; |
`MULUH,`MULSUH,`MULH: IsMul = TRUE; |
default: IsMul = FALSE; |
endcase |
else |
IsMul = FALSE; |
`MULUI,`MULI: IsMul = TRUE; |
2924,12 → 2848,13
function IsDivmod; |
input [47:0] isn; |
case(isn[`INSTRUCTION_OP]) |
`RR: |
`R2: |
if (isn[`INSTRUCTION_L2]==2'b00) |
case(isn[`INSTRUCTION_S2]) |
`DIVMODU,`DIVMODSU,`DIVMOD: IsDivmod = TRUE; |
default: IsDivmod = FALSE; |
endcase |
case(isn[`INSTRUCTION_S2]) |
`DIVU,`DIVSU,`DIV: IsDivmod = TRUE; |
`MODU,`MODSU,`MOD: IsDivmod = TRUE; |
default: IsDivmod = FALSE; |
endcase |
else |
IsDivmod = FALSE; |
`DIVUI,`DIVI,`MODI: IsDivmod = TRUE; |
5367,12 → 5292,13
wire id1_clk, id2_clk, id3_clk; |
|
// Always at least one decoder |
BUFGCE uclkb2 |
( |
.I(clk_i), |
.CE(id1_available), |
.O(id1_clk) |
); |
assign id1_clk = clk_i; |
//BUFGCE uclkb2 |
//( |
// .I(clk_i), |
// .CE(id1_available), |
// .O(id1_clk) |
//); |
|
FT64_idecoder uid1 |
( |
5392,12 → 5318,13
|
generate begin : gIDUInst |
if (`NUM_IDU > 1) begin |
BUFGCE uclkb3 |
( |
.I(clk_i), |
.CE(id2_available), |
.O(id2_clk) |
); |
//BUFGCE uclkb3 |
//( |
// .I(clk_i), |
// .CE(id2_available), |
// .O(id2_clk) |
//); |
assign id2_clk = clk_i; |
|
FT64_idecoder uid2 |
( |
5416,12 → 5343,13
); |
end |
if (`NUM_IDU > 2) begin |
BUFGCE uclkb4 |
( |
.I(clk_i), |
.CE(id3_available), |
.O(id3_clk) |
); |
//BUFGCE uclkb4 |
//( |
// .I(clk_i), |
// .CE(id3_available), |
// .O(id3_clk) |
//); |
assign id3_clk = clk_i; |
|
FT64_idecoder uid2 |
( |
5511,12 → 5439,14
generate begin : gFPUInst |
if (`NUM_FPU > 0) begin |
wire fpu1_clk; |
BUFGCE ufpc1 |
( |
.I(clk_i), |
.CE(fpu1_available), |
.O(fpu1_clk) |
); |
//BUFGCE ufpc1 |
//( |
// .I(clk_i), |
// .CE(fpu1_available), |
// .O(fpu1_clk) |
//); |
assign fpu1_clk = clk_i; |
|
fpUnit ufp1 |
( |
.rst(rst), |
5537,12 → 5467,13
end |
if (`NUM_FPU > 1) begin |
wire fpu2_clk; |
BUFGCE ufpc2 |
( |
.I(clk_i), |
.CE(fpu2_available), |
.O(fpu2_clk) |
); |
//BUFGCE ufpc2 |
//( |
// .I(clk_i), |
// .CE(fpu2_available), |
// .O(fpu2_clk) |
//); |
assign fpu2_clk = clk_i; |
fpUnit ufp1 |
( |
.rst(rst), |
5773,9 → 5704,9
iqentry_memready[6] = (iqentry_v[6] & iqentry_memopsvalid[6] & ~iqentry_memissue[6] & ~iqentry_done[6] & ~iqentry_out[6] & ~iqentry_stomp[6]), |
iqentry_memready[7] = (iqentry_v[7] & iqentry_memopsvalid[7] & ~iqentry_memissue[7] & ~iqentry_done[7] & ~iqentry_out[7] & ~iqentry_stomp[7]); |
|
assign outstanding_stores = (dram0 && IsStore(dram0_instr)) || |
(dram1 && IsStore(dram1_instr)) || |
(dram2 && IsStore(dram2_instr)); |
assign outstanding_stores = (dram0 && dram0_store) || |
(dram1 && dram1_store) || |
(dram2 && dram2_store); |
|
// |
// additional COMMIT logic |
6296,7 → 6227,7
waitctr <= waitctr - 64'd1; |
|
|
if (IsFlowCtrl(iqentry_instr[fcu_id[`QBITS]]) && iqentry_v[fcu_id[`QBITS]] && !iqentry_done[fcu_id[`QBITS]] && iqentry_out[fcu_id[`QBITS]]) |
if (iqentry_fc[fcu_id[`QBITS]] && iqentry_v[fcu_id[`QBITS]] && !iqentry_done[fcu_id[`QBITS]] && iqentry_out[fcu_id[`QBITS]]) |
fcu_timeout <= fcu_timeout + 8'd1; |
|
if (branchmiss) begin |
7050,17 → 6981,17
// |
// set the IQ entry == DONE as soon as the SW is let loose to the memory system |
// |
if (mem1_available && dram0 == `DRAMSLOT_BUSY && IsStore(dram0_instr)) begin |
if (mem1_available && dram0 == `DRAMSLOT_BUSY && dram0_store) begin |
if ((alu0_v && (dram0_id[`QBITS] == alu0_id[`QBITS])) || (alu1_v && (dram0_id[`QBITS] == alu1_id[`QBITS]))) panic <= `PANIC_MEMORYRACE; |
iqentry_done[ dram0_id[`QBITS] ] <= `VAL; |
iqentry_out[ dram0_id[`QBITS] ] <= `INV; |
end |
if (mem2_available && `NUM_MEM > 1 && dram1 == `DRAMSLOT_BUSY && IsStore(dram1_instr)) begin |
if (mem2_available && `NUM_MEM > 1 && dram1 == `DRAMSLOT_BUSY && dram1_store) begin |
if ((alu0_v && (dram1_id[`QBITS] == alu0_id[`QBITS])) || (alu1_v && (dram1_id[`QBITS] == alu1_id[`QBITS]))) panic <= `PANIC_MEMORYRACE; |
iqentry_done[ dram1_id[`QBITS] ] <= `VAL; |
iqentry_out[ dram1_id[`QBITS] ] <= `INV; |
end |
if (mem3_available && `NUM_MEM > 2 && dram2 == `DRAMSLOT_BUSY && IsStore(dram2_instr)) begin |
if (mem3_available && `NUM_MEM > 2 && dram2 == `DRAMSLOT_BUSY && dram2_store) begin |
if ((alu0_v && (dram2_id[`QBITS] == alu0_id[`QBITS])) || (alu1_v && (dram2_id[`QBITS] == alu1_id[`QBITS]))) panic <= `PANIC_MEMORYRACE; |
iqentry_done[ dram2_id[`QBITS] ] <= `VAL; |
iqentry_out[ dram2_id[`QBITS] ] <= `INV; |
7449,7 → 7380,7
dramA_id <= dram0_id; |
dramA_exc <= dram0_exc; |
dramA_bus <= fnDati(dram0_instr,dram0_addr,rdat0); |
if (IsStore(dram0_instr)) $display("m[%h] <- %h", dram0_addr, dram0_data); |
if (dram0_store) $display("m[%h] <- %h", dram0_addr, dram0_data); |
end |
// else |
// dramA_v <= `INV; |
7459,7 → 7390,7
dramB_id <= dram1_id; |
dramB_exc <= dram1_exc; |
dramB_bus <= fnDati(dram1_instr,dram1_addr,rdat1); |
if (IsStore(dram1_instr)) $display("m[%h] <- %h", dram1_addr, dram1_data); |
if (dram1_store) $display("m[%h] <- %h", dram1_addr, dram1_data); |
end |
// else |
// dramB_v <= `INV; |
7469,7 → 7400,7
dramC_id <= dram2_id; |
dramC_exc <= dram2_exc; |
dramC_bus <= fnDati(dram2_instr,dram2_addr,rdat2); |
if (IsStore(dram2_instr)) $display("m[%h] <- %h", dram2_addr, dram2_data); |
if (dram2_store) $display("m[%h] <- %h", dram2_addr, dram2_data); |
end |
// else |
// dramC_v <= `INV; |
7513,9 → 7444,10
// if (ol[iqentry_thrd[n]]==`OL_USER) |
// dram0_seg <= (iqentry_Ra[n]==5'd30 || iqentry_Ra[n]==5'd31) ? {ss[iqentry_thrd[n]],13'd0} : {ds[iqentry_thrd[n]],13'd0}; |
// else |
dram0_unc <= iqentry_a1[n][31:20]==12'hFFD || !dce || IsVolatileLoad(iqentry_instr[n]); |
dram0_memsize <= MemSize(iqentry_instr[n]); |
dram0_unc <= iqentry_a1[n][39:20]==20'hFFFFD || !dce || iqentry_loadv[n]; |
dram0_memsize <= iqentry_memsz[n]; |
dram0_load <= iqentry_load[n]; |
dram0_store <= iqentry_store[n]; |
dram0_ol <= (iqentry_Ra[n][4:0]==5'd31 || iqentry_Ra[n][4:0]==5'd30) ? ol[iqentry_thrd[n]] : dl[iqentry_thrd[n]]; |
// Once the memory op is issued reset the a1_v flag. |
// This will cause the a1 bus to look for new data from memory (a1_s is pointed to a memory bus) |
7542,9 → 7474,10
// if (ol[iqentry_thrd[n]]==`OL_USER) |
// dram1_seg <= (iqentry_Ra[n]==5'd30 || iqentry_Ra[n]==5'd31) ? {ss[iqentry_thrd[n]],13'd0} : {ds[iqentry_thrd[n]],13'd0}; |
// else |
dram1_unc <= iqentry_a1[n][31:20]==12'hFFD || !dce || IsVolatileLoad(iqentry_instr[n]); |
dram1_memsize <= MemSize(iqentry_instr[n]); |
dram1_unc <= iqentry_a1[n][39:20]==20'hFFFFD || !dce || iqentry_loadv[n]; |
dram1_memsize <= iqentry_memsz[n]; |
dram1_load <= iqentry_load[n]; |
dram1_store <= iqentry_store[n]; |
dram1_ol <= (iqentry_Ra[n][4:0]==5'd31 || iqentry_Ra[n][4:0]==5'd30) ? ol[iqentry_thrd[n]] : dl[iqentry_thrd[n]]; |
iqentry_a1_v[n] <= `INV; |
last_issue = n; |
7569,9 → 7502,10
// if (ol[iqentry_thrd[n]]==`OL_USER) |
// dram2_seg <= (iqentry_Ra[n]==5'd30 || iqentry_Ra[n]==5'd31) ? {ss[iqentry_thrd[n]],13'd0} : {ds[iqentry_thrd[n]],13'd0}; |
// else |
dram2_unc <= iqentry_a1[n][31:20]==12'hFFD || !dce || IsVolatileLoad(iqentry_instr[n]); |
dram2_memsize <= MemSize(iqentry_instr[n]); |
dram2_unc <= iqentry_a1[n][39:20]==20'hFFFFD || !dce || iqentry_loadv[n]; |
dram2_memsize <= iqentry_memsz[n]; |
dram2_load <= iqentry_load[n]; |
dram2_store <= iqentry_store[n]; |
dram2_ol <= (iqentry_Ra[n][4:0]==5'd31 || iqentry_Ra[n][4:0]==5'd30) ? ol[iqentry_thrd[n]] : dl[iqentry_thrd[n]]; |
iqentry_a1_v[n] <= `INV; |
end |
7602,6 → 7536,8
oddball_commit(commit0_v, head0); |
if (`NUM_CMT > 1) |
oddball_commit(commit1_v, head1); |
//if (`NUM_CMT > 2) |
// oddball_commit(commit2_v, head2); |
|
// Fetch and queue are limited to two instructions per cycle, so we might as |
// well limit retiring to two instructions max to conserve logic. |
7650,7 → 7586,7
head_inc(1); |
end |
6'b0?_11_11: |
if (`NUM_CMT > 2 || (`NUM_CMT > 1 && iqentry_tgt[head2] == 12'd0)) begin |
if (`NUM_CMT > 2 || (`NUM_CMT > 1 && iqentry_tgt[head2] == 12'd0 && !iqentry_oddball[head2] && ~|iqentry_exc[head2])) begin |
iqentry_v[head1] <= `INV; |
iqentry_v[head2] <= `INV; |
head_inc(3); |
7686,7 → 7622,7
end |
6'b11_0?_11: |
if (head1 != tail0) begin |
if (`NUM_CMT > 2 || iqentry_tgt[head2]==12'd0) begin |
if (`NUM_CMT > 2 || (iqentry_tgt[head2]==12'd0 && !iqentry_oddball[head2] && ~|iqentry_exc[head2])) begin |
iqentry_v[head0] <= `INV; |
iqentry_v[head2] <= `INV; |
head_inc(3); |
7736,7 → 7672,7
head_inc(1); |
end |
6'b11_11_11: |
if (`NUM_CMT > 2 || (`NUM_CMT > 1 && iqentry_tgt[head2]==12'd0)) begin |
if (`NUM_CMT > 2 || (`NUM_CMT > 1 && iqentry_tgt[head2]==12'd0 && !iqentry_oddball[head2] && ~|iqentry_exc[head2])) begin |
iqentry_v[head0] <= `INV; |
iqentry_v[head1] <= `INV; |
iqentry_v[head2] <= `INV; |
8025,7 → 7961,7
bstate <= B12; |
end |
end |
else if (mem1_available && dram0==`DRAMSLOT_BUSY && IsStore(dram0_instr)) begin |
else if (mem1_available && dram0==`DRAMSLOT_BUSY && dram0_store) begin |
`ifdef SUPPORT_DBG |
if (dbg_smatch0) begin |
dramA_v <= `TRUE; |
8067,7 → 8003,7
// cr_o <= IsSWC(dram0_instr); |
end |
end |
else if (mem2_available && dram1==`DRAMSLOT_BUSY && IsStore(dram1_instr) && `NUM_MEM > 1) begin |
else if (mem2_available && dram1==`DRAMSLOT_BUSY && dram1_store && `NUM_MEM > 1) begin |
`ifdef SUPPORT_DBG |
if (dbg_smatch1) begin |
dramB_v <= `TRUE; |
8109,7 → 8045,7
// cr_o <= IsSWC(dram0_instr); |
end |
end |
else if (mem3_available && dram2==`DRAMSLOT_BUSY && IsStore(dram2_instr) && `NUM_MEM > 2) begin |
else if (mem3_available && dram2==`DRAMSLOT_BUSY && dram2_store && `NUM_MEM > 2) begin |
`ifdef SUPPORT_DBG |
if (dbg_smatch2) begin |
dramC_v <= `TRUE; |
9117,8 → 9053,12
iqentry_fpu [nn] <= bus[`IB_FPU]; |
iqentry_fc [nn] <= bus[`IB_FC]; |
iqentry_canex[nn] <= bus[`IB_CANEX]; |
iqentry_loadv[nn] <= bus[`IB_LOADV]; |
iqentry_load [nn] <= bus[`IB_LOAD]; |
iqentry_preload[nn]<= bus[`IB_PRELOAD]; |
iqentry_store[nn] <= bus[`IB_STORE]; |
iqentry_oddball[nn] <= bus[`IB_ODDBALL]; |
iqentry_memsz[nn] <= bus[`IB_MEMSZ]; |
iqentry_mem [nn] <= bus[`IB_MEM]; |
iqentry_memndx[nn] <= bus[`IB_MEMNDX]; |
iqentry_rmw [nn] <= bus[`IB_RMW]; |
9257,29 → 9197,6
end |
endtask |
|
function IsOddball; |
input [`QBITS] head; |
if (|iqentry_exc[head]) |
IsOddball = TRUE; |
else |
case(iqentry_instr[head][`INSTRUCTION_OP]) |
`BRK: IsOddball = TRUE; |
`IVECTOR: |
case(iqentry_instr[head][`INSTRUCTION_S2]) |
`VSxx: IsOddball = TRUE; |
default: IsOddball = FALSE; |
endcase |
`RR: |
case(iqentry_instr[head][`INSTRUCTION_S2]) |
`VMOV: IsOddball = TRUE; |
`SEI,`RTI,`CACHEX: IsOddball = TRUE; |
default: IsOddball = FALSE; |
endcase |
`CSRRW,`REX,`CACHE,`FLOAT: IsOddball = TRUE; |
default: IsOddball = FALSE; |
endcase |
endfunction |
|
// This task takes care of commits for things other than the register file. |
task oddball_commit; |
input v; |
/rtl/twoway/FT64_regfile2w6r_oc.v
30,7 → 30,7
parameter RBIT = 11; |
input clka; |
input ena; |
input [8:0] wea; |
input [7:0] wea; |
input [RBIT:0] addra; |
input [WID-1:0] dina; |
input clkb; |
56,7 → 56,6
always @(posedge clka) if (ena & wea[5]) mem[addra][47:40] <= dina[47:40]; |
always @(posedge clka) if (ena & wea[6]) mem[addra][55:48] <= dina[55:48]; |
always @(posedge clka) if (ena & wea[7]) mem[addra][63:56] <= dina[63:56]; |
always @(posedge clka) if (ena & wea[8]) mem[addra][64] <= dina[64]; |
|
always @(posedge clkb) |
raddrb <= addrb; |
73,8 → 72,8
input clk; |
input wr0; |
input wr1; |
input [8:0] we0; |
input [8:0] we1; |
input [7:0] we0; |
input [7:0] we1; |
input [RBIT:0] wa0; |
input [RBIT:0] wa1; |
input [WID-1:0] i0; |
186,7 → 185,9
.dina(i), |
.clkb(rclk), |
.enb(1'b1), |
.web(1'b0), |
.addrb(ra0), |
.dinb(8'h00), |
.doutb(o00) |
); |
|
198,7 → 199,9
.dina(i), |
.clkb(rclk), |
.enb(1'b1), |
.web(1'b0), |
.addrb(ra1), |
.dinb(8'h00), |
.doutb(o01) |
); |
|
210,7 → 213,9
.dina(i), |
.clkb(rclk), |
.enb(1'b1), |
.web(1'b0), |
.addrb(ra2), |
.dinb(8'h00), |
.doutb(o02) |
); |
|
222,7 → 227,9
.dina(i), |
.clkb(rclk), |
.enb(1'b1), |
.web(1'b0), |
.addrb(ra3), |
.dinb(8'h00), |
.doutb(o03) |
); |
|
234,7 → 241,9
.dina(i), |
.clkb(rclk), |
.enb(1'b1), |
.web(1'b0), |
.addrb(ra4), |
.dinb(8'h00), |
.doutb(o04) |
); |
|
246,7 → 255,9
.dina(i), |
.clkb(rclk), |
.enb(1'b1), |
.web(1'b0), |
.addrb(ra5), |
.dinb(8'h00), |
.doutb(o05) |
); |
`endif |
/software/AS64/source/FT64.cpp
1345,7 → 1345,7
need(','); |
NextToken(); |
val = expr(); |
if (opcode6==0x05LL) { // subi |
if (opcode6==-4LL) { // subi |
val = -val; |
opcode6 = 0x04LL; // change to addi |
} |
1629,7 → 1629,7
// add r1,r2,r3 |
// --------------------------------------------------------------------------- |
|
static void process_rrop(int64_t funct6) |
static void process_rrop(int64_t funct6, int64_t iop) |
{ |
int Ra,Rb,Rt,Rbp,Rtp; |
char *p; |
1644,8 → 1644,10
need(','); |
NextToken(); |
if (token=='#') { |
if (iop < 0 && iop!=-4) |
printf("Immediate mode not supported (%d).", lineno); |
inptr = p; |
process_riop(funct6); |
process_riop(iop); |
return; |
} |
prevToken(); |
2706,7 → 2708,7
emit_insn( |
(2 << 12) | |
(((val >> 4) & 0x0F) << 8) | |
(2 << 7) | |
(2 << 6) | |
(((val >> 3) & 1) << 5), |
0, 2 |
); |
3452,7 → 3454,7
// lw r1,[r2+r3] |
// ---------------------------------------------------------------------------- |
|
static void ProcessLoadVolatile(int opcode3) |
static void ProcessLoadVolatile(int64_t opcode, int sz) |
{ |
int Ra,Rb; |
int Rt; |
3474,37 → 3476,63
expect(','); |
mem_operand(&disp, &Ra, &Rb, &Sc); |
if (Ra > 0 && Rb > 0) { |
switch (sz) { |
case -1: opcode = 0x01; // LVBUX |
case 1: opcode = 0x00; // LVBX |
case -2: opcode = 0x03; // LVCUX |
case 2: opcode = 0x02; // LVCX |
case -4: opcode = 0x05; // LVHUX |
case 4: opcode = 0x04; // LVHX |
case 8: opcode = 0x06; // LVWX |
} |
emit_insn( |
(0x3B << 26) | |
(opcode3 << 23) | |
(Sc << 21) | |
(Rt << 16) | |
(Rb << 11) | |
(Ra << 6) | |
0x02,!expand_flag,4); |
(opcode << 26) | |
(Sc << 23) | |
(Rt << 18) | |
(Rb << 13) | |
(Ra << 8) | |
0x16,!expand_flag,4); |
return; |
} |
if (Ra < 0) Ra = 0; |
val = disp; |
if (val < -2048 || val > 2047) { |
LoadConstant12(val,23); |
if (!IsNBit(val, 30)) { |
LoadConstant(val, 23); |
// Change to indexed addressing |
switch (sz) { |
case -1: opcode = 0x01; // LVBUX |
case 1: opcode = 0x00; // LVBX |
case -2: opcode = 0x03; // LVCUX |
case 2: opcode = 0x02; // LVCX |
case -4: opcode = 0x05; // LVHUX |
case 4: opcode = 0x04; // LVHX |
case 8: opcode = 0x06; // LVWX |
} |
emit_insn( |
(0x3B << 26) | |
(opcode3 << 23) | |
(Rt << 16) | |
(23 << 11) | |
(Ra << 6) | |
0x02,!expand_flag,4); |
(opcode << 26LL) | |
(0 << 23) | // Sc = 0 |
(Rt << 18) | |
(23 << 13) | |
(Ra << 8) | |
0x02, !expand_flag, 4); |
ScanToEOL(); |
return; |
} |
if (!IsNBit(val, 14)) { |
emit_insn( |
((val | abs(sz)) << 18LL) | |
(Rt << 13) | |
(Ra << 8) | |
(1 << 6) | |
opcode, !expand_flag, 6); |
ScanToEOL(); |
return; |
} |
emit_insn( |
(opcode3 << 28) | |
((val & 0xFFF) << 16) | |
(Rt << 11) | |
(Ra << 6) | |
0x3B,!expand_flag,4); |
((val | abs(sz)) << 18LL) | |
(Rt << 13) | |
(Ra << 8) | |
opcode, !expand_flag, 4); |
ScanToEOL(); |
} |
|
3795,7 → 3823,8
return; |
} |
emit_insn( |
(fn << 26LL) | |
(fn << 26LL) | // fn should be even |
(((rgs >> 5) & 1) << 26) | |
(d3 << 23LL) | |
(rgs << 18) | |
(Rt << 13) | |
4409,10 → 4438,10
// case tk_add: process_add(); break; |
// case tk_abs: process_rop(0x04); break; |
case tk_abs: process_rop(0x01); break; |
case tk_add: process_rrop(0x04); break; |
case tk_add: process_rrop(0x04,0x04); break; |
case tk_addi: process_riop(0x04); break; |
case tk_align: process_align(); continue; break; |
case tk_and: process_rrop(0x08); break; |
case tk_and: process_rrop(0x08,0x08); break; |
case tk_andi: process_riop(0x08); break; |
case tk_asl: process_shift(0x2); break; |
case tk_asr: process_shift(0x3); break; |
4456,10 → 4485,10
case tk_cli: emit_insn(0xC0000002,0,4); break; |
case tk_chk: process_chk(0x34); break; |
case tk_cmovenz: process_cmove(0x29); break; |
case tk_cmp: process_rrop(0x06); break; |
case tk_cmpi: process_riop(0x06); break; |
case tk_cmpu: process_rrop(0x07); break; |
case tk_cmpui: process_riop(0x07); break; |
//case tk_cmp: process_rrop(0x06); break; |
//case tk_cmpi: process_riop(0x06); break; |
//case tk_cmpu: process_rrop(0x07); break; |
//case tk_cmpui: process_riop(0x07); break; |
case tk_code: process_code(); break; |
case tk_com: process_com(); break; |
case tk_csrrc: process_csrrw(0x3); break; |
4483,12 → 4512,14
case tk_dec: process_inc(0x25); break; |
case tk_dh: process_dh(); break; |
case tk_dh_htbl: process_dh_htbl(); break; |
case tk_div: process_riop(0x3E); break; |
case tk_dw: process_dw(); break; |
case tk_div: process_rrop(0x3E,0x3E); break; |
//case tk_divsu: process_rrop(0x3D, -1); break; |
case tk_divu: process_rrop(0x3C,0x3C); break; |
case tk_dw: process_dw(); break; |
case tk_end: goto j1; |
case tk_end_expand: expandedBlock = 0; break; |
case tk_endpublic: break; |
case tk_eor: process_rrrop(0x0A); break; |
case tk_eor: process_rrop(0x0A,0x0A); break; |
case tk_eori: process_riop(0x0A); break; |
case tk_extern: process_extern(); break; |
case tk_ftoi: process_ftoi(0x12); break; |
4525,25 → 4556,30
case tk_lhu: process_load(0x20,-2); break; |
//case tk_lui: process_lui(0x27); break; |
case tk_lv: process_lv(0x36); break; |
case tk_lvb: ProcessLoadVolatile(0); break; |
case tk_lvc: ProcessLoadVolatile(2); break; |
case tk_lvh: ProcessLoadVolatile(4); break; |
case tk_lvw: ProcessLoadVolatile(6); break; |
case tk_lvb: ProcessLoadVolatile(0x3B,1); break; |
case tk_lvbu: ProcessLoadVolatile(0x3B,-1); break; |
case tk_lvc: ProcessLoadVolatile(0x3B,2); break; |
case tk_lvcu: ProcessLoadVolatile(0x3B,-2); break; |
case tk_lvh: ProcessLoadVolatile(0x3B,4); break; |
case tk_lvhu: ProcessLoadVolatile(0x3B,-4); break; |
case tk_lvw: ProcessLoadVolatile(0x3B,8); break; |
case tk_lw: process_load(0x20,4); break; |
case tk_lwr: process_load(0x1D,0); break; |
case tk_memdb: emit_insn(0x40100002,0,4); break; |
case tk_memsb: emit_insn(0x40110002,0,4); break; |
case tk_memdb: emit_insn(0x04400002,0,4); break; |
case tk_memsb: emit_insn(0x04440002,0,4); break; |
case tk_message: process_message(); break; |
case tk_mod: process_riop(0x2E); break; |
case tk_modu: process_riop(0x2C); break; |
case tk_mod: process_rrop(0x16,0x2E); break; |
case tk_modu: process_rrop(0x14,-1); break; |
case tk_mov: process_mov(0x02, 0x22); break; |
case tk_mul: process_riop(0x3A); break; |
case tk_mulu: process_riop(0x38); break; |
case tk_neg: process_neg(); break; |
case tk_mul: process_rrop(0x3A,0x3A); break; |
//case tk_mulh: process_rrop(0x26, 0x3A); break; |
case tk_mulu: process_rrop(0x38,0x38); break; |
//case tk_muluh: process_rrop(0x24, 0x38); break; |
case tk_neg: process_neg(); break; |
case tk_nop: emit_insn(0x1C,0,4); break; |
case tk_not: process_rop(0x05); break; |
// case tk_not: process_rop(0x07); break; |
case tk_or: process_rrop(0x09); break; |
case tk_or: process_rrop(0x09,0x09); break; |
case tk_ori: process_riop(0x09); break; |
case tk_org: process_org(); break; |
case tk_plus: expand_flag = 1; break; |
4595,7 → 4631,7
case tk_slli: process_shifti(0x8); break; |
case tk_srai: process_shifti(0xB); break; |
case tk_srli: process_shifti(0x9); break; |
case tk_sub: process_rrop(0x05); break; |
case tk_sub: process_rrop(0x05,-0x04); break; |
case tk_subi: process_riop(0x05); break; |
case tk_sv: process_sv(0x37); break; |
case tk_sw: process_store(0x24,4); break; |
4605,7 → 4641,7
case tk_sxb: process_rop(0x1A); break; |
case tk_sxc: process_rop(0x19); break; |
case tk_sxh: process_rop(0x18); break; |
case tk_sync: emit_insn(0x04120002,0,4); break; |
case tk_sync: emit_insn(0x04480002,0,4); break; |
//case tk_unlink: emit_insn((0x1B << 26) | (0x1F << 16) | (30 << 11) | (0x1F << 6) | 0x02,0,4); break; |
case tk_vadd: process_vrrop(0x04); break; |
case tk_vadds: process_vsrrop(0x14); break; |
4622,8 → 4658,8
case tk_vsubs: process_vsrrop(0x15); break; |
case tk_vxor: process_vrrop(0x0A); break; |
case tk_vxors: process_vsrrop(0x1A); break; |
case tk_xnor: process_rrop(0x0E); break; |
case tk_xor: process_rrop(0x0A); break; |
case tk_xnor: process_rrop(0x0E,0x0E); break; |
case tk_xor: process_rrop(0x0A,0x0A); break; |
case tk_xori: process_riop(0x0A); break; |
case tk_zxb: process_rop(0x0A); break; |
case tk_zxc: process_rop(0x09); break; |
/software/AS64/source/token.cpp
1796,20 → 1796,41
return (token = tk_lwr); |
} |
} |
if (gCpu==4) { |
if (gCpu==4 || gCpu=='F') { |
if ((inptr[1]=='v' || inptr[1]=='V') && (inptr[2]=='b' || inptr[2]=='B') && isspace(inptr[3])) { |
inptr += 3; |
return token = tk_lvb; |
} |
if ((inptr[1]=='v' || inptr[1]=='V') && (inptr[2]=='c' || inptr[2]=='C') && isspace(inptr[3])) { |
if ((inptr[1] == 'v' || inptr[1] == 'V') |
&& (inptr[2] == 'b' || inptr[2] == 'B') |
&& (inptr[3] == 'u' || inptr[3] == 'U') |
&& isspace(inptr[4])) { |
inptr += 4; |
return token = tk_lvbu; |
} |
if ((inptr[1]=='v' || inptr[1]=='V') && (inptr[2]=='c' || inptr[2]=='C') && isspace(inptr[3])) { |
inptr += 3; |
return token = tk_lvc; |
} |
if ((inptr[1]=='v' || inptr[1]=='V') && (inptr[2]=='h' || inptr[2]=='H') && isspace(inptr[3])) { |
if ((inptr[1] == 'v' || inptr[1] == 'V') |
&& (inptr[2] == 'c' || inptr[2] == 'C') |
&& (inptr[3] == 'u' || inptr[3] == 'U') |
&& isspace(inptr[4])) { |
inptr += 4; |
return token = tk_lvcu; |
} |
if ((inptr[1]=='v' || inptr[1]=='V') && (inptr[2]=='h' || inptr[2]=='H') && isspace(inptr[3])) { |
inptr += 3; |
return token = tk_lvh; |
} |
if ((inptr[1]=='v' || inptr[1]=='V') && (inptr[2]=='w' || inptr[2]=='W') && isspace(inptr[3])) { |
if ((inptr[1] == 'v' || inptr[1] == 'V') |
&& (inptr[2] == 'h' || inptr[2] == 'H') |
&& (inptr[3] == 'u' || inptr[3] == 'U') |
&& isspace(inptr[4])) { |
inptr += 4; |
return token = tk_lvhu; |
} |
if ((inptr[1]=='v' || inptr[1]=='V') && (inptr[2]=='w' || inptr[2]=='W') && isspace(inptr[3])) { |
inptr += 3; |
return token = tk_lvw; |
} |
1978,7 → 1999,7
inptr += 6; |
return token = tk_mv2fix; |
} |
if (gCpu==4) { |
if (gCpu==4 || gCpu=='F') { |
if ((inptr[1]=='e' || inptr[1]=='E') && |
(inptr[2]=='m' || inptr[2]=='M') && |
(inptr[3]=='d' || inptr[3]=='D') && |
/software/AS64/source/token.h
256,8 → 256,11
tk_lui, |
tk_lv, |
tk_lvb, |
tk_lvbu, |
tk_lvc, |
tk_lvcu, |
tk_lvh, |
tk_lvhu, |
tk_lvw, |
tk_lvwar, |
tk_lw, |
277,6 → 280,7
tk_mfspr, |
tk_mod, |
tk_modi, |
tk_modsu, |
tk_modu, |
tk_modui, |
tk_mov, |
283,8 → 287,12
tk_mtfp, |
tk_mtspr, |
tk_mul, |
tk_mulh, |
tk_muli, //290 |
tk_mulsu, |
tk_mulsuh, |
tk_mulu, |
tk_muluh, |
tk_mului, |
tk_mv2fix, |
tk_mv2flt, |