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

Subversion Repositories thor

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /thor/trunk/FT64v7/rtl/common
    from Rev 60 to Rev 61
    Reverse comparison

Rev 60 → Rev 61

/FT64_EvalBranch.v
1,6 → 1,6
// ============================================================================
// __
// \\__/ o\ (C) 2017-2018 Robert Finch, Waterloo
// \\__/ o\ (C) 2017-2019 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
24,6 → 24,7
// ============================================================================
//
`define TRUE 1'b1
`define BNEI 6'h12
`define BBc 6'h26
`define Bcc 6'h30
`define BEQI 6'h32
36,6 → 37,12
`define BGE 3'h3
`define BLTU 3'h6
`define BGEU 3'h7
`define BAND 3'h0
`define BOR 3'h1
`define BXOR 3'd2
`define BNAND 3'h4
`define BNOR 3'h5
`define BXNOR 3'd6
 
`define IBNE 2'd2
`define DBNZ 2'd3
63,7 → 70,18
`BGEU: takb <= a >= b;
default: takb <= `TRUE;
endcase
`BLcc:
case(instr[15:13])
`BAND: takb <= a != 0 && b != 0;
`BOR: takb <= a != 0 || b != 0;
`BXOR: takb <= (a != 0) ^ (b != 0);
`BNAND: takb <= !(a != 0 && b != 0);
`BNOR: takb <= !(a != 0 || b != 0);
`BXNOR: takb <= !((a != 0) ^ (b != 0));
default: takb <= `TRUE;
endcase
`BEQI: takb <= a=={{56{instr[22]}},instr[22:18],instr[15:13]};
`BNEI: takb <= a!={{56{instr[22]}},instr[22:18],instr[15:13]};
`BBc:
case(instr[14:13])
2'd0: takb <= a[{instr[22:18],instr[15]}]; // BBS
/FT64_FCU_Calc.v
1,6 → 1,6
// ============================================================================
// __
// \\__/ o\ (C) 2017-2018 Robert Finch, Waterloo
// \\__/ o\ (C) 2017-2019 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
/FT64_InsLength.v
1,6 → 1,6
// ============================================================================
// __
// \\__/ o\ (C) 2018 Robert Finch, Waterloo
// \\__/ o\ (C) 2018-2019 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
/FT64_alu.v
1,6 → 1,6
// ============================================================================
// __
// \\__/ o\ (C) 2017-2018 Robert Finch, Waterloo
// \\__/ o\ (C) 2017-2019 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
25,15 → 25,10
`include "FT64_defines.vh"
`include "FT64_config.vh"
 
module FT64_alu(rst, clk, ld, abort, instr, sz, tlb, store, a, b, c, pc, Ra, tgt, tgt2, ven, vm,
module FT64_alu(rst, clk, ld, abort, instr, sz, tlb, store, a, b, c, t, pc, Ra, tgt, tgt2, ven, vm,
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,
exv_o, rdv_o, wrv_o
`ifdef SUPPORT_SEGMENTATION
, zs_base, ds_base, es_base, fs_base, gs_base, hs_base, ss_base, cs_base,
zsub, dsub, esub, fsub, gsub, hsub, ssub, csub,
zslb, dslb, eslb, fslb, gslb, hslb, sslb, cslb
`endif
`ifdef SUPPORT_BBMS
, pb, cbl, cbu, ro, dbl, dbu, sbl, sbu, en
`endif
45,6 → 40,7
parameter TRUE = 1'b1;
parameter FALSE = 1'b0;
parameter PTR = 20'hFFF01;
parameter BASE_SHIFT = 13'd0;
input rst;
input clk;
input ld;
56,6 → 52,7
input [63:0] a;
input [63:0] b;
input [63:0] c;
input [63:0] t; // target register value
input [31:0] pc;
input [11:0] Ra;
input [11:0] tgt;
89,32 → 86,6
output wrv_o;
output rdv_o;
output exv_o;
`ifdef SUPPORT_SEGMENTATION
input [63:0] zs_base;
input [63:0] ds_base;
input [63:0] es_base;
input [63:0] fs_base;
input [63:0] gs_base;
input [63:0] hs_base;
input [63:0] ss_base;
input [63:0] cs_base;
input [63:0] zslb;
input [63:0] dslb;
input [63:0] eslb;
input [63:0] fslb;
input [63:0] gslb;
input [63:0] hslb;
input [63:0] sslb;
input [63:0] cslb;
input [63:0] zsub;
input [63:0] dsub;
input [63:0] esub;
input [63:0] fsub;
input [63:0] gsub;
input [63:0] hsub;
input [63:0] ssub;
input [63:0] csub;
`endif
`ifdef SUPPORT_BBMS
input [63:0] pb;
input [63:0] cbl;
140,48 → 111,9
 
reg adrDone, adrIdle;
reg [63:0] usa; // unsegmented address
`ifdef SUPPORT_SEGMENTATION
reg [63:0] pb;
reg [63:0] ub;
reg [63:0] lb;
always @*
case(usa[63:61])
3'd0: pb <= zs_base;
3'd1: pb <= ds_base;
3'd2: pb <= es_base;
3'd3: pb <= fs_base;
3'd4: pb <= gs_base;
3'd5: pb <= hs_base;
3'd6: pb <= ss_base;
3'd7: pb <= cs_base;
endcase
always @*
case(usa[63:61])
3'd0: ub <= zsub;
3'd1: ub <= dsub;
3'd2: ub <= esub;
3'd3: ub <= fsub;
3'd4: ub <= gsub;
3'd5: ub <= hsub;
3'd6: ub <= ssub;
3'd7: ub <= csub;
endcase
always @*
case(usa[63:61])
3'd0: lb <= zslb;
3'd1: lb <= dslb;
3'd2: lb <= eslb;
3'd3: lb <= fslb;
3'd4: lb <= gslb;
3'd5: lb <= hslb;
3'd6: lb <= sslb;
3'd7: lb <= cslb;
endcase
`else
`ifndef SUPPORT_BBMS
reg [63:0] pb = 64'h0;
`endif
`endif
reg [63:0] addro;
reg [63:0] adr; // load / store address
reg [63:0] shift8;
317,15 → 249,38
 
function IsShiftAndOp;
input [47:0] isn;
IsShiftAndOp = FALSE;
if (isn[`INSTRUCTION_L2]==2'b01) begin
case(isn[`INSTRUCTION_OP])
`R2:
case(isn[47:42])
`SHIFTR: IsShiftAndOp = TRUE;
default: IsShiftAndOp = FALSE;
endcase
default: IsShiftAndOp = FALSE;
endcase
end
else
IsShiftAndOp = FALSE;
endfunction
 
wire [63:0] bfout,shfto;
wire [63:0] shftob;
wire [63:0] shftco;
reg [63:0] shift10;
 
always @(posedge clk)
shift9 <= shift8;
always @*
case (instr[41:36])
`ADD: shift10 <= shift9 + c;
`SUB: shift10 <= shift9 - c;
`AND: shift10 <= shift9 & c;
`OR: shift10 <= shift9 | c;
`XOR: shift10 <= shift9 ^ c;
6'h20: shift10 <= ~shift9; // COM
6'h21: shift10 <= !shift9; // NOT
default: shift10 <= shift9;
endcase
 
wire tlb_done, tlb_idle;
wire [DBW-1:0] tlbo;
623,7 → 578,8
.idle(div_idle)
);
 
wire [5:0] bshift = instr[31:26]==`SHIFTR ? b[5:0] : {instr[30],instr[22:18]};
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]});
 
FT64_shift ushft1
(
800,6 → 756,11
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,
|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] 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] 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]};
wire [63:0] zxb10 = {54'd0,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]};
978,7 → 939,7
endcase
case(instr[35:33])
`ASL,`ASR,`SHL,`SHR,`ROL,`ROR:
o[63:0] = shift9;
o[63:0] = shift10;
default: o[63:0] = 64'hDCDCDCDCDCDCDCDC;
endcase
end
1039,6 → 1000,13
2'd2: o = {-a[63:32],-a[31:0]};
2'd3: o = -a;
endcase
`REDAND:
case(sz[1:0])
2'd0: o = redand8;
2'd1: o = redand16;
2'd2: o = redand32;
2'd3: o = redand64;
endcase
`REDOR: case(sz[1:0])
2'd0: o = redor8;
2'd1: o = redor16;
1056,13 → 1024,22
endcase
`BMM: o[63:0] = BIG ? bmmo : 64'hCCCCCCCCCCCCCCCC;
`SHIFT31,
`SHIFT63,
`SHIFT63:
begin
if (instr[25:23]==`SHL || instr[25:23]==`ASL)
o = shfto;
else
o = BIG ? shfto : 64'hCCCCCCCCCCCCCCCC;
$display("BIG=%d",BIG);
if(!BIG)
$stop;
end
`SHIFTR:
begin
if (instr[25:23]==`SHL || instr[25:23]==`ASL)
o[63:0] = shfto;
o = shfto;
else
o[63:0] = BIG ? shfto : 64'hCCCCCCCCCCCCCCCC;
o = BIG ? shfto : 64'hCCCCCCCCCCCCCCCC;
$display("BIG=%d",BIG);
if(!BIG)
$stop;
1101,12 → 1078,18
`else
o = a + b;
`endif
// If the operation is SIMD the target register must be passed in arg T.
`SUB:
`ifdef SIMD
case(sz)
3'd0,3'd4:
3'd0:
begin
o[7:0] = a[7:0] - b[7:0];
o[63:8] = t[63:8];
end
3'd4:
begin
o[7:0] = a[7:0] - b[7:0];
o[15:8] = a[15:8] - b[15:8];
o[23:16] = a[23:16] - b[23:16];
o[31:24] = a[31:24] - b[31:24];
1135,6 → 1118,7
`else
o = a - b;
`endif
`SEQ: tskSeq(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);
`SLE: tskSle(instr,instr[25:23],a,b,o);
1175,37 → 1159,56
end
`MIN:
`ifdef SIMD
case(sz)
3'd0,3'd4:
begin
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[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[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[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;
end
3'd1,3'd5:
begin
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[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;
end
3'd2,3'd6:
begin
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;
end
3'd3,3'd7:
case(sz)
3'd0:
begin
o[7:0] = BIG ? ($signed(a[7:0]) < $signed(b[7:0]) ? a[7:0] : b[7:0]) : 8'hCC;
o[63:8] = BIG ? t[63:8] : 56'hCCCCCCCCCCCCCC;
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[63:0] = BIG ? ($signed(a) < $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
end
endcase
o = BIG ? ($signed(a) < $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
end
3'd4:
begin
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[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[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[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;
end
3'd5:
begin
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[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;
end
3'd6:
begin
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;
end
3'd7:
begin
o = BIG ? ($signed(a) < $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
end
endcase
`else
o[63:0] = BIG ? ($signed(a) < $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
o = BIG ? ($signed(a) < $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
`endif
`MAX:
`ifdef SIMD
1287,7 → 1290,7
`LHX,`LHUX,`LWX,`LWRX:
if (BIG) begin
usa = a + (c << instr[19:18]);
o = {pb[50:0],13'd0} + usa;
o = {pb[50:0],BASE_SHIFT} + usa;
end
else
o = 64'hCCCCCCCCEEEEEEEE;
1294,7 → 1297,7
`LVX,`SVX:
if (BIG) begin
usa = a + (c << 2'd3);
o = {pb[50:0],13'd0} + usa;
o = {pb[50:0],BASE_SHIFT} + usa;
end
else
o = 64'hCCCCCCCCCCCCCCCC;
1301,7 → 1304,7
`LVWS,`SVWS:
if (BIG) begin
usa = a + ({c * ven,3'b000});
o = {pb[50:0],13'd0} + usa;
o = {pb[50:0],BASE_SHIFT} + usa;
end
else
o = 64'hCCCCCCCCCCCCCCCC;
1312,18 → 1315,18
`PUSH:
begin
usa = a - 4'd8;
o = {pb[50:0],13'd0} + usa;
o = {pb[50:0],BASE_SHIFT} + usa;
end
`SBX,`SCX,`SHX,`SWX,`SWCX:
if (BIG) begin
usa = a + (c << instr[14:13]);
o = {pb[50:0],13'd0} + usa;
o = {pb[50:0],BASE_SHIFT} + usa;
end
else
o = 64'hCCCCCCCCEEEEEEEE;
`SVX: if (BIG) begin
usa = a + (c << 2'd3);
o = {pb[50:0],13'd0} + usa;
o = {pb[50:0],BASE_SHIFT} + usa;
end
else
o = 64'hCCCCCCCCCCCCCCCC;
1330,7 → 1333,7
`SVWS:
if (BIG) begin
usa = a + ({c * ven,3'b000});
o = {pb[50:0],13'd0} + usa;
o = {pb[50:0],BASE_SHIFT} + usa;
end
else
o = 64'hCCCCCCCCCCCCCCCC;
1356,6 → 1359,7
o = {{15{instr[31]}},instr[31:18],instr[12:8],30'd0};
end
`ADDI: o = a + b;
`SEQI: o = a == b;
`SLTI: o = $signed(a) < $signed(b);
`SLTUI: o = a < b;
`SGTI: o = $signed(a) > $signed(b);
1373,37 → 1377,40
`LB,`LBU,`SB:
begin
usa = a + b;
o = {pb[50:0],13'd0} + usa;
o = {pb[50:0],BASE_SHIFT} + usa;
end
`Lx,`LxU,`Sx,`LVx,`LVxU:
casez(b[2:0])
3'b100:
begin
usa = a + {b[63:3],3'b0}; // LW / SW
o = {pb[50:0],BASE_SHIFT} + usa;
end
3'b?10:
begin
usa = a + {b[63:2],2'b0}; // LH / LHU / SH
o = {pb[50:0],BASE_SHIFT} + usa;
end
default:
begin
usa = a + {b[63:1],1'b0}; // LC / LCU / SC
o = {pb[50:0],BASE_SHIFT} + usa;
end
endcase
`PUSHC:
begin
casez(b[2:0])
3'b100:
begin
usa = a + {b[63:3],3'b0}; // LW / SW
o = {pb[50:0],13'd0} + usa;
end
3'b?10:
begin
usa = a + {b[63:2],2'b0}; // LH / LHU / SH
o = {pb[50:0],13'd0} + usa;
end
default:
begin
usa = a + {b[63:1],1'b0}; // LC / LCU / SC
o = {pb[50:0],13'd0} + usa;
end
endcase
usa = a - 4'd8;
o = {pb[50:0],BASE_SHIFT} + usa;
end
`LWR,`SWC,`CAS,`CACHE:
begin
usa = a + b;
o = {pb[50:0],13'd0} + usa;
o = {pb[50:0],BASE_SHIFT} + usa;
end
`LV,`SV:
begin
usa = a + b + {ven,3'b0};
o = {pb[50:0],13'd0} + usa;
o = {pb[50:0],BASE_SHIFT} + usa;
end
`CSRRW:
case(instr[27:18])
1569,11 → 1576,6
`CSRRW: exc <= (instr[27:21]==7'b0011011) ? `FLT_SEG : `FLT_NONE;
`MEMNDX:
begin
`ifdef SUPPORT_SEGMENTATION
if (usa < {lb[50:0],13'h0000} && usa > {ub[50:0],13'h1fff} && dl!=2'b00)
exc <= (Ra[4:0]==5'd30 || Ra[4:0]==5'd31) ? `FLT_STK : `FLT_SGB;
else
`endif
`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)
exc <= `FLT_STK;
1602,7 → 1604,7
if (BIG) begin
case({instr[31:28],instr[22:21]})
`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;
`LWX,`LVWX,`LWRX,
`CACHEX,`LVX: exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
1618,7 → 1620,7
case({instr[31:28],instr[17:16]})
`PUSH: exc <= |o[2:0] ? `FLT_ALN : `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;
`SWX,`SWCX: exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
`SVX: exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
1634,11 → 1636,6
exc <= `FLT_UNIMP;
end
end
`ifdef SUPPORT_SEGMENTATION
`LB,`LBU,`SB:
if (usa < {lb[50:0],13'h0000} && usa > {ub[50:0],13'h1fff} && dl!=2'b00)
exc <= (Ra[4:0]==5'd30 || Ra[4:0]==5'd31) ? `FLT_STK : `FLT_SGB;
`endif
`ifdef SUPPORT_BBMS
`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)
1654,11 → 1651,6
`endif
`Lx,`Sx,`LxU,`LVx,`LVxU:
begin
`ifdef SUPPORT_SEGMENTATION
if (usa < {lb[50:0],13'h0000} && usa > {ub[50:0],13'h1fff} && dl!=2'b00)
exc <= (Ra[4:0]==5'd30 || Ra[4:0]==5'd31) ? `FLT_STK : `FLT_SGB;
else
`endif
`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)
exc <= `FLT_STK;
1673,18 → 1665,13
else
`endif
casez(b[2:0])
3'b100: exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE; // LW / SW
3'b?10: exc <= |o[1:0] ? `FLT_ALN : `FLT_NONE; // LH / LHU / SH
default: exc <= |o[ 0] ? `FLT_ALN : `FLT_NONE; // LC / LCU / SC
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
default: exc <= o[ 0] ? `FLT_ALN : `FLT_NONE; // LC / LCU / SC
endcase
end
`LWR,`SWC,`CAS,`CACHE:
begin
`ifdef SUPPORT_SEGMENTATION
if (usa < {lb[50:0],13'h0000} && usa > {ub[50:0],13'h1fff} && dl!=2'b00)
exc <= (Ra[4:0]==5'd30 || Ra[4:0]==5'd31) ? `FLT_STK : `FLT_SGB;
else
`endif
`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)
exc <= `FLT_STK;
1698,7 → 1685,7
exc <= `FLT_WRV;
else
`endif
exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
exc <= o[2:0]!=3'b0 ? `FLT_ALN : `FLT_NONE;
end
default: exc <= `FLT_NONE;
endcase
1712,6 → 1699,47
bb <= c;
end
 
task tskSeq;
input [47:0] instr;
input [2:0] sz;
input [63:0] a;
input [63:0] b;
output [63:0] o;
begin
`ifdef SIMD
case(sz[2: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'd2: o[63:0] = $signed(a[31:0]) == $signed(b[31:0]);
3'd3: o[63:0] = $signed(a) == $signed(b);
3'd4: o[63:0] = {
7'h0,$signed(a[7:0]) == $signed(b[7:0]),
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[63:56]) == $signed(b[63:56])
};
3'd5: o[63:0] = {
15'h0,$signed(a[15:0]) == $signed(b[15:0]),
15'h0,$signed(a[31:16]) == $signed(b[31:16]),
15'h0,$signed(a[47:32]) == $signed(b[47:32]),
15'h0,$signed(a[63:48]) == $signed(b[63:48])
};
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])
};
3'd7: o[63:0] = $signed(a[63:0]) == $signed(b[63:0]);
endcase
`else
o = $signed(a) == $signed(b);
`endif
end
endtask
 
task tskSlt;
input [47:0] instr;
input [2:0] sz;
1789,7 → 1817,7
3'd7: o[63:0] = $signed(a[63:0]) <= $signed(b[63:0]);
endcase
`else
o[63:0] = $signed(a[63:0]) <= $signed(b[63:0]);
o = $signed(a) <= $signed(b);
`endif
end
endtask
/FT64_config.vh
1,6 → 1,6
// ============================================================================
// __
// \\__/ o\ (C) 2017-2018 Robert Finch, Waterloo
// \\__/ o\ (C) 2017-2019 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
33,6 → 33,10
//`define SUPPORT_SEGMENTATION 1'b1
//`define SUPPORT_PREDICATION 1'b1
//`define DEBUG_LOGIC 1'b1
 
// The following define generates rtl to support 40-bit jumps and calls,
// otherwise only 24-bit jumps and calls are supported.
//`define JMP40 1'b1
`define L1_ICACHE_SIZE 2 // 2 or 4 for 2 or 4 kB
 
// One way to tweak the size of the core a little bit is to limit the number
89,7 → 93,7
// Comment out the following to remove FCU enhancements (branch predictor, BTB, RSB)
//`define FCU_ENH 1
// Comment out the following to remove bypassing logic on the functional units
//`define FU_BYPASS 1
`define FU_BYPASS 1
 
//`define SUPPORT_TLB 1
 
/FT64_defines.vh
1,6 → 1,6
// ============================================================================
// __
// \\__/ o\ (C) 2017-2018 Robert Finch, Waterloo
// \\__/ o\ (C) 2017-2019 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
126,9 → 126,11
`define MEMDB 5'h10
`define MEMSB 5'h11
`define SYNC 5'h12
`define EXEC 5'h13
`define CHAIN_OFF 5'h14
`define CHAIN_ON 5'h15
`define SETWB 5'h16
`define REDAND 5'h17
`define SXH 5'h18
`define SXC 5'h19
`define SXB 5'h1A
142,6 → 144,7
`define AND 6'h08
`define OR 6'h09
`define XOR 6'h0A
`define SEQ 6'h0B
`define NAND 6'h0C
`define NOR 6'h0D
`define XNOR 6'h0E
172,6 → 175,7
`define RTI 6'h32
`define RTE 6'h32
`define VMOV 6'h33
`define MOV2SEG 6'h37
`define MULU 6'h38
`define MULSU 6'h39
`define MUL 6'h3A
188,14 → 192,21
`define ANDI 6'h08
`define ORI 6'h09
`define XORI 6'h0A
`define EXEC 6'h0B
`define SEQI 6'h0B
`define REX 6'h0D
`define XNORI 6'h0E
`define FLOAT 6'h0F
`define LDCS 6'h10
`define BLcc 6'h10
`define BAND 3'd0
`define BOR 3'd1
`define BXOR 3'd2
`define BNAND 3'd4
`define BNOR 3'd5
`define BXOR 3'd6
`define LVxU 6'h11
`define CMPI 6'h12
`define BNEI 6'h12
`define LB 6'h13
`define PUSHC 6'h14
`define SB 6'h15
`define MEMNDX 6'h16
`define LVBX 6'h00
313,6 → 324,7
`define EXR 8'h7F
 
`define NOP_INSN {42'd0,`NOP}
`define PFI 16'h1F80 // reserved for PFI
`define INSN_FLT_EXF 16'h1180
`define INSN_FLT_IBE 16'h10A0
`define INSN_FLT_TLB 16'h1280
374,6 → 386,7
`define CSR_BM_CTR 10'h3C1
`define CSR_ICL_CTR 10'h3C2
`define CSR_IRQ_CTR 10'h3C3
`define CSR_BR_CTR 10'h3C4
`define CSR_TIME 10'h3E0
`define CSR_INFO 10'b11_1111_????
 
425,16 → 438,9
`define FLT_BD 8'd55
`define FLT_STK 8'd56
`define FLT_DBE 8'd60
`define FLT_RET 8'd230
`define FLT_CS 8'd231
`define FLT_ZS_LD 8'd232
`define FLT_DS_LD 8'd233
`define FLT_ES_LD 8'd234
`define FLT_FS_LD 8'd235
`define FLT_GS_LD 8'd236
`define FLT_HS_LD 8'd237
`define FLT_SS_LD 8'd238
`define FLT_CS_LD 8'd239
`define FLT_STP 8'd232 // segment type
`define FLT_STZ 8'd233 // stack segment zero
`define FLT_SNP 8'd234 // segment not present
 
`define INSTRUCTION_OP 5:0
`define INSTRUCTION_L2 7:6
485,6 → 491,7
`define IB_RC 70:66
`define IB_RB 65:61
`define IB_RA 60:56
`define IB_LOADSEG 53
`define IB_PRFW 52
`define IB_CMP 51
`define IB_PUSH 47
/FT64_icache.v
1,6 → 1,6
// ============================================================================
// __
// \\__/ o\ (C) 2017-2018 Robert Finch, Waterloo
// \\__/ o\ (C) 2017-2019 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
34,16 → 34,16
 
module FT64_L1_icache_mem(rst, clk, wr, en, lineno, i, o, ov, invall, invline);
parameter pLines = 64;
parameter pLineWidth = 298;
parameter pLineWidth = 306;
localparam pLNMSB = pLines==128 ? 6 : 5;
input rst;
input clk;
input wr;
input [8:0] en;
input [9:0] en;
input [pLNMSB:0] lineno;
input [pLineWidth-1:0] i;
output [pLineWidth-1:0] o;
output [8:0] ov;
output [9:0] ov;
input invall;
input invline;
 
60,6 → 60,7
reg [pLines-1:0] valid6;
reg [pLines-1:0] valid7;
reg [pLines-1:0] valid8;
reg [pLines-1:0] valid9;
 
initial begin
for (n = 0; n < pLines; n = n + 1)
83,8 → 84,10
always @(posedge clk)
if (wr & en[7]) mem[lineno][255:224] <= i[255:224];
always @(posedge clk)
if (wr & en[8]) mem[lineno][297:256] <= i[297:256];
if (wr & en[8]) mem[lineno][287:256] <= i[287:256];
always @(posedge clk)
if (wr & en[9]) mem[lineno][305:288] <= i[305:288];
always @(posedge clk)
if (rst) begin
valid0 <= 64'd0;
valid1 <= 64'd0;
95,6 → 98,7
valid6 <= 64'd0;
valid7 <= 64'd0;
valid8 <= 64'd0;
valid9 <= 64'd0;
end
else begin
if (invall) begin
107,6 → 111,7
valid6 <= 64'd0;
valid7 <= 64'd0;
valid8 <= 64'd0;
valid9 <= 64'd0;
end
else if (invline) begin
valid0[lineno] <= 1'b0;
118,6 → 123,7
valid6[lineno] <= 1'b0;
valid7[lineno] <= 1'b0;
valid8[lineno] <= 1'b0;
valid9[lineno] <= 1'b0;
end
else if (wr) begin
if (en[0]) valid0[lineno] <= 1'b1;
129,6 → 135,7
if (en[6]) valid6[lineno] <= 1'b1;
if (en[7]) valid7[lineno] <= 1'b1;
if (en[8]) valid8[lineno] <= 1'b1;
if (en[9]) valid9[lineno] <= 1'b1;
end
end
 
142,6 → 149,7
assign ov[6] = valid6[lineno];
assign ov[7] = valid7[lineno];
assign ov[8] = valid8[lineno];
assign ov[9] = valid9[lineno];
 
endmodule
 
214,6 → 222,10
reg [AMSB+8-5:0] mem2 [0:pLines/4-1];
reg [AMSB+8-5:0] mem3 [0:pLines/4-1];
reg [AMSB+8:0] rradr;
reg [pLines/4-1:0] mem0v;
reg [pLines/4-1:0] mem1v;
reg [pLines/4-1:0] mem2v;
reg [pLines/4-1:0] mem3v;
integer n;
initial begin
for (n = 0; n < pLines/4; n = n + 1)
242,10 → 254,29
end
end
 
wire hit0 = mem0[adr[pMSB:5]]==adr[AMSB+8:5];
wire hit1 = mem1[adr[pMSB:5]]==adr[AMSB+8:5];
wire hit2 = mem2[adr[pMSB:5]]==adr[AMSB+8:5];
wire hit3 = mem3[adr[pMSB:5]]==adr[AMSB+8:5];
always @(posedge clk)
if (rst) begin
mem0v <= 1'd0;
mem1v <= 1'd0;
mem2v <= 1'd0;
mem3v <= 1'd0;
end
else begin
if (wr) begin
case(lfsro[1:0])
2'b00: begin mem0v[adr[pMSB:5]] <= 1'b1; end
2'b01: begin mem1v[adr[pMSB:5]] <= 1'b1; end
2'b10: begin mem2v[adr[pMSB:5]] <= 1'b1; end
2'b11: begin mem3v[adr[pMSB:5]] <= 1'b1; end
endcase
end
end
 
 
wire hit0 = mem0[adr[pMSB:5]]==adr[AMSB+8:5] & mem0v[adr[pMSB:5]];
wire hit1 = mem1[adr[pMSB:5]]==adr[AMSB+8:5] & mem1v[adr[pMSB:5]];
wire hit2 = mem2[adr[pMSB:5]]==adr[AMSB+8:5] & mem2v[adr[pMSB:5]];
wire hit3 = mem3[adr[pMSB:5]]==adr[AMSB+8:5] & mem3v[adr[pMSB:5]];
always @*
//if (wr2) lineno = wlineno;
if (hit0) lineno = {2'b00,adr[pMSB:5]};
324,10 → 355,10
input nxt;
input wr;
output wr_ack;
input [8:0] en;
input [9:0] en;
input [AMSB+8:0] adr;
input [AMSB+8:0] wadr;
input [297:0] i;
input [305:0] i;
output reg [55:0] o;
output reg [1:0] fault;
output hit;
334,14 → 365,14
input invall;
input invline;
 
wire [297:0] ic;
reg [297:0] i1, i2;
wire [8:0] lv; // line valid
wire [305:0] ic;
reg [305:0] i1, i2;
wire [9:0] lv; // line valid
wire [pLNMSB:0] lineno;
wire [pLNMSB:0] wlineno;
wire taghit;
reg wr1,wr2;
reg [8:0] en1, en2;
reg [9:0] en1, en2;
reg invline1, invline2;
 
// Must update the cache memory on the cycle after a write to the tag memmory.
351,7 → 382,7
always @(posedge clk)
wr2 <= wr1;
always @(posedge clk)
i1 <= i[297:0];
i1 <= i[305:0];
always @(posedge clk)
i2 <= i1;
always @(posedge clk)
424,13 → 455,13
endgenerate
 
// Valid if a 64-bit area encompassing a potential 48-bit instruction is valid.
assign hit = taghit & lv[adr[4:2]] & lv[adr[4:2]+4'd1];
assign hit = taghit & |lv;//[adr[4:2]];// & lv[adr[4:2]+4'd1];
 
//always @(radr or ic0 or ic1)
always @(adr or ic)
o <= ic >> {adr[4:0],3'h0};
always @*
fault <= ic[297:296];
fault <= ic[305:304];
 
assign wr_ack = wr2;
 
446,7 → 477,7
input [2:0] sel;
input [63:0] i;
input [1:0] fault;
output [297:0] o;
output [305:0] o;
output reg ov;
input invall;
input invline;
456,7 → 487,7
reg [63:0] mem1 [0:511];
reg [63:0] mem2 [0:511];
reg [63:0] mem3 [0:511];
reg [39:0] mem4 [0:511];
reg [47:0] mem4 [0:511];
reg [1:0] memf [0:511];
reg [511:0] valid;
reg [8:0] rrcl;
484,7 → 515,7
3'd1: begin mem1[lineno] <= i; memf[lineno] <= memf[lineno] | fault; end
3'd2: begin mem2[lineno] <= i; memf[lineno] <= memf[lineno] | fault; end
3'd3: begin mem3[lineno] <= i; memf[lineno] <= memf[lineno] | fault; end
3'd4: begin mem4[lineno] <= i[39:0]; memf[lineno] <= memf[lineno] | fault; end
3'd4: begin mem4[lineno] <= i[47:0]; memf[lineno] <= memf[lineno] | fault; end
endcase
end
end
523,7 → 554,7
input exv_i;
input [63:0] i;
input err_i;
output [297:0] o;
output [305:0] o;
output hit;
input invall;
input invline;
/FT64_idecoder.v
1,6 → 1,6
// ============================================================================
// __
// \\__/ o\ (C) 2017-2018 Robert Finch, Waterloo
// \\__/ o\ (C) 2017-2019 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
48,6 → 48,7
parameter wyde = 3'd1;
parameter tetra = 3'd2;
parameter octa = 3'd3;
parameter hexi = 3'd4;
 
// Really IsPredictableBranch
// Does not include BccR's
97,8 → 98,10
IsALU = TRUE;
`BRK: IsALU = FALSE;
`Bcc: IsALU = FALSE;
`BLcc: IsALU = FALSE;
`BBc: IsALU = FALSE;
`BEQI: IsALU = FALSE;
`BNEI: IsALU = FALSE;
`CHK: IsALU = FALSE;
`JAL: IsALU = FALSE;
`JMP: IsALU = FALSE;
178,8 → 181,10
default: IsFlowCtrl <= FALSE;
endcase
`Bcc: IsFlowCtrl <= TRUE;
`BLcc: IsFlowCtrl <= TRUE;
`BBc: IsFlowCtrl <= TRUE;
`BEQI: IsFlowCtrl <= TRUE;
`BNEI: IsFlowCtrl <= TRUE;
`CHK: IsFlowCtrl <= TRUE;
`JAL: IsFlowCtrl <= TRUE;
`JMP: IsFlowCtrl <= TRUE;
250,7 → 255,7
// Had branches that could exception if looping to self. But in a tight loop
// it affects store performance.
// -> A branch may only exception if it loops back to itself.
`Bcc,`BBc,`BEQI: fnCanException = isn[7] ? brdisp == 11'h7FF : brdisp == 11'h7FE;
`Bcc,`BLcc,`BBc,`BEQI,`BNEI: fnCanException = isn[7] ? brdisp == 11'h7FF : brdisp == 11'h7FE;
`CHK: fnCanException = TRUE;
default:
// Stores can stil exception if there is a write buffer, but we allow following
257,9 → 262,9
// stores to be issued by ignoring the fact they can exception because the stores
// can be undone by invalidating the write buffer.
`ifdef HAS_WB
fnCanException = IsMem(isn) && !IsStore(isn);
fnCanException = IsMem && !IsStore(isn);
`else
fnCanException = IsMem(isn);
fnCanException = IsMem;
`endif
endcase
end
281,9 → 286,32
endcase
endfunction
 
function IsMov2Seg;
input [47:0] isn;
case(isn[`INSTRUCTION_OP])
`R2:
if (isn[6])
IsMov2Seg = isn[47:42]==`MOV2SEG;
else
case(isn[`INSTRUCTION_S2])
`MOV2SEG: IsMov2Seg = TRUE;
`RTI: IsMov2Seg = TRUE;
default: IsMov2Seg = FALSE;
endcase
`RET:
IsMov2Seg = TRUE;
default: IsMov2Seg = FALSE;
endcase
endfunction
 
function IsVolatileLoad;
input [47:0] isn;
case(isn[`INSTRUCTION_OP])
`R2:
if (isn[6])
IsVolatileLoad = isn[47:42]==`MOV2SEG;
else
IsVolatileLoad = isn[31:26]==`MOV2SEG;
`MEMNDX:
if (isn[`INSTRUCTION_L2]==2'b00)
case({isn[31:28],isn[22:21]})
334,6 → 362,7
endcase
else
IsStore = FALSE;
`PUSHC: IsStore = TRUE;
`SB: IsStore = TRUE;
`Sx: IsStore = TRUE;
`SWC: IsStore = TRUE;
365,13 → 394,33
endcase
else
IsPush = FALSE;
`PUSHC: IsPush = TRUE;
default: IsPush = FALSE;
endcase
endfunction
 
function [0:0] IsMem;
function IsPushc;
input [47:0] isn;
case(isn[`INSTRUCTION_OP])
`PUSHC: IsPushc = TRUE;
default: IsPushc = FALSE;
endcase
endfunction
 
//function [0:0] IsMem;
reg IsMem;
always @*
//input [47:0] isn;
case(instr[`INSTRUCTION_OP])
`R2:
if (instr[6])
IsMem = instr[47:42]==`MOV2SEG;
else
case(instr[`INSTRUCTION_S2])
`MOV2SEG: IsMem = TRUE;
`RTI: IsMem = TRUE;
default: IsMem = FALSE;
endcase
`MEMNDX: IsMem = TRUE;
`AMO: IsMem = TRUE;
`LB: IsMem = TRUE;
381,6 → 430,7
`LWR: IsMem = TRUE;
`LV,`SV: IsMem = TRUE;
`INC: IsMem = TRUE;
`PUSHC: IsMem = TRUE;
`SB: IsMem = TRUE;
`Sx: IsMem = TRUE;
`SWC: IsMem = TRUE;
387,9 → 437,10
`CAS: IsMem = TRUE;
`LVx: IsMem = TRUE;
`LVxU: IsMem = TRUE;
//`RET: IsMem = TRUE;???
default: IsMem = FALSE;
endcase
endfunction
//endfunction
 
function IsMemNdx;
input [47:0] isn;
441,10 → 492,11
MemSize = octa;
`LB,`LBU: MemSize = byt;
`Lx,`LxU,`LVx,`LVxU:
casez(isn[20:18])
3'b100: MemSize = octa;
3'b?10: MemSize = tetra;
3'b??1: MemSize = wyde;
casez(isn[21:18])
4'b1000: MemSize = hexi;
4'b?100: MemSize = octa;
4'b??10: MemSize = tetra;
4'b???1: MemSize = wyde;
default: MemSize = octa;
endcase
`LWR: MemSize = octa;
459,14 → 511,16
endcase
`SB: MemSize = byt;
`Sx:
casez(isn[15:13])
3'b100: MemSize = octa;
3'b?10: MemSize = tetra;
3'b??1: MemSize = wyde;
casez(isn[16:13])
4'b1000: MemSize = hexi;
4'b?100: MemSize = octa;
4'b??10: MemSize = tetra;
4'b???1: MemSize = wyde;
default: MemSize = octa;
endcase
`SWC: MemSize = octa;
`SV: MemSize = octa;
`PUSHC: MemSize = octa;
default: MemSize = octa;
endcase
endfunction
563,22 → 617,6
endcase
endfunction
 
function IsCmp;
input [47:0] isn;
case(isn[`INSTRUCTION_OP])
`R2:
if (isn[`INSTRUCTION_L2]==2'b00)
case(isn[31:26])
`CMP: IsCmp = TRUE;
default: IsCmp = FALSE;
endcase
else
IsCmp = FALSE;
`CMPI: IsCmp = TRUE;
default: IsCmp = FALSE;
endcase
endfunction
 
function IsLWRX;
input [47:0] isn;
case(isn[`INSTRUCTION_OP])
621,8 → 659,10
input [47:0] isn;
casez(isn[`INSTRUCTION_OP])
`Bcc: IsBranch = TRUE;
`BLcc: IsBranch = TRUE;
`BBc: IsBranch = TRUE;
`BEQI: IsBranch = TRUE;
`BNEI: IsBranch = TRUE;
`CHK: IsBranch = TRUE;
default: IsBranch = FALSE;
endcase
655,7 → 695,7
 
function IsSync;
input [47:0] isn;
IsSync = (isn[`INSTRUCTION_OP]==`R2 && isn[`INSTRUCTION_L2]==2'b00 && isn[`INSTRUCTION_S2]==`R1 && isn[22:18]==`SYNC) || IsRti(isn);
IsSync = (isn[`INSTRUCTION_OP]==`R2 && isn[`INSTRUCTION_L2]==2'b00 && isn[`INSTRUCTION_S2]==`R1 && isn[22:18]==`SYNC) || IsRti(isn) || IsMov2Seg(isn);
endfunction
 
// Has an extendable 14-bit constant
663,6 → 703,7
input [47:0] isn;
casez(isn[`INSTRUCTION_OP])
`ADDI: HasConst = TRUE;
`SEQI: HasConst = TRUE;
`SLTI: HasConst = TRUE;
`SLTUI: HasConst = TRUE;
`SGTI: HasConst = TRUE;
694,6 → 735,7
`RET: HasConst = TRUE;
`LVx: HasConst = TRUE;
`LVxU: HasConst = TRUE;
`PUSHC: HasConst = TRUE;
default: HasConst = FALSE;
endcase
endfunction
742,6 → 784,7
endcase
`ADD: IsRFW = TRUE;
`SUB: IsRFW = TRUE;
`SEQ: IsRFW = TRUE;
`SLT: IsRFW = TRUE;
`SLTU: IsRFW = TRUE;
`SLE: IsRFW = TRUE;
839,6 → 882,7
`BBc: IsRFW = FALSE;
`BITFIELD: IsRFW = TRUE;
`ADDI: IsRFW = TRUE;
`SEQI: IsRFW = TRUE;
`SLTI: IsRFW = TRUE;
`SLTUI: IsRFW = TRUE;
`SGTI: IsRFW = TRUE;
864,6 → 908,7
`LV: IsRFW = TRUE;
`LVx: IsRFW = TRUE;
`LVxU: IsRFW = TRUE;
`PUSHC: IsRFW = TRUE;
`CAS: IsRFW = TRUE;
`AMO: IsRFW = TRUE;
`CSRRW: IsRFW = TRUE;
882,7 → 927,6
`CMP: fnWe = 8'h00; // CMP sets predicate registers so doesn't update general register file.
default: fnWe = 8'hFF;
endcase
`CMPI: fnWe = 8'h00;
default: fnWe = 8'hFF;
endcase
/*
932,8 → 976,10
casez(isn[`INSTRUCTION_OP])
`BRK: Source1Valid = TRUE;
`Bcc: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
`BLcc: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
`BBc: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
`BEQI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
`BNEI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
`CHK: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
`R2: case(isn[`INSTRUCTION_S2])
`SHIFT31: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
943,6 → 989,7
endcase
`MEMNDX: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
`ADDI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
`SEQI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
`SLTI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
`SLTUI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
`SGTI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
964,6 → 1011,7
`Sx: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
`SWC: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
`SV: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
`PUSHC: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
`INC: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
`CAS: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
`JAL: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
984,14 → 1032,15
casez(isn[`INSTRUCTION_OP])
`BRK: Source2Valid = TRUE;
`Bcc: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
`BLcc: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
`BBc: Source2Valid = TRUE;
`BEQI: Source2Valid = TRUE;
`BNEI: Source2Valid = TRUE;
`CHK: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
`R2: case(isn[`INSTRUCTION_S2])
`R1: Source2Valid = TRUE;
`SHIFTR: Source2Valid = isn[25] ? 1'b1 : isn[`INSTRUCTION_RB]==5'd0;
`SHIFT31: Source2Valid = isn[25] ? 1'b1 : isn[`INSTRUCTION_RB]==5'd0;
`SHIFT63: Source2Valid = isn[25] ? 1'b1 : isn[`INSTRUCTION_RB]==5'd0;
`SHIFT31: Source2Valid = TRUE;
`SHIFT63: Source2Valid = TRUE;
default: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
endcase
`MEMNDX:
1006,6 → 1055,7
default: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
endcase
`ADDI: Source2Valid = TRUE;
`SEQI: Source2Valid = TRUE;
`SLTI: Source2Valid = TRUE;
`SLTUI: Source2Valid = TRUE;
`SGTI: Source2Valid = TRUE;
1025,6 → 1075,7
`SB: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
`Sx: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
`SWC: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
`PUSHC: Source2Valid = TRUE;
`CAS: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
`JAL: Source2Valid = TRUE;
`RET: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
1096,8 → 1147,9
`endif
begin
bus <= 144'h0;
bus[`IB_CMP] <= IsCmp(instr);
if (IsStore(instr))
bus[`IB_LOADSEG] <= IsMov2Seg(instr);
bus[`IB_CMP] <= 1'b0;//IsCmp(instr);
if (IsStore(instr) & !IsPushc(instr))
bus[`IB_CONST] <= instr[6]==1'b1 ? {{34{instr[47]}},instr[47:23],instr[17:13]} :
{{50{instr[31]}},instr[31:23],instr[17:13]};
else
1143,7 → 1195,7
bus[`IB_PUSH] <= IsPush(instr);
bus[`IB_ODDBALL] <= IsOddball(instr);
bus[`IB_MEMSZ] <= MemSize(instr);
bus[`IB_MEM] <= IsMem(instr);
bus[`IB_MEM] <= IsMem;
bus[`IB_MEMNDX] <= IsMemNdx(instr);
bus[`IB_RMW] <= IsCAS(instr) || IsAMO(instr) || IsInc(instr);
bus[`IB_MEMDB] <= IsMemdb(instr);
1157,7 → 1209,7
bus[`IB_SYNC] <= IsSync(instr)||IsBrk(instr)||IsRti(instr);
bus[`IB_FSYNC] <= IsFSync(instr);
bus[`IB_RFW] <= (Rt==5'd0) ? 1'b0 : IsRFW(instr);// && !IsCmp(instr);
bus[`IB_PRFW] <= IsCmp(instr);
bus[`IB_PRFW] <= 1'b0;//IsCmp(instr);
bus[`IB_WE] <= fnWe(instr);
id_o <= id_i;
idv_o <= idv_i;
1184,8 → 1236,10
IsALU = TRUE;
`BRK: IsALU = FALSE;
`Bcc: IsALU = FALSE;
`BLcc: IsALU = FALSE;
`BBc: IsALU = FALSE;
`BEQI: IsALU = FALSE;
`BNEI: IsALU = FALSE;
`CHK: IsALU = FALSE;
`JAL: IsALU = FALSE;
`JMP: IsALU = FALSE;
/FT64_iexpander.v
1,6 → 1,6
// ============================================================================
// __
// \\__/ o\ (C) 2017-2018 Robert Finch, Waterloo
// \\__/ o\ (C) 2017-2019 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
157,7 → 157,7
expand[17:13] = fnRp(cinstr[2:0]);
expand[12:8] = fnRp(cinstr[2:0]);
expand[7:6] = 2'b10;
expand[5:0] = 8'h02; // R2 instruction
expand[5:0] = 6'h02; // R2 instruction
end
2'd1: begin
expand[47:32] = 16'h0000;
167,7 → 167,7
expand[17:13] = fnRp(cinstr[2:0]);
expand[12:8] = fnRp(cinstr[2:0]);
expand[7:6] = 2'b10;
expand[5:0] = 8'h02; // R2 instruction
expand[5:0] = 6'h02; // R2 instruction
end
2'd2: begin
expand[47:32] = 16'h0000;
177,7 → 177,7
expand[17:13] = fnRp(cinstr[2:0]);
expand[12:8] = fnRp(cinstr[2:0]);
expand[7:6] = 2'b10;
expand[5:0] = 8'h02; // R2 instruction
expand[5:0] = 6'h02; // R2 instruction
end
2'd3: begin
expand[47:32] = 16'h0000;
187,7 → 187,7
expand[17:13] = fnRp(cinstr[2:0]);
expand[12:8] = fnRp(cinstr[2:0]);
expand[7:6] = 2'b10;
expand[5:0] = 8'h02; // R2 instruction
expand[5:0] = 6'h02; // R2 instruction
end
endcase
endcase
198,7 → 198,7
expand[22:18] = 5'd0; // Rb = 0
expand[17:16] = cinstr[1:0];
expand[15:13] = 3'd0; // BEQ
expand[12:8] = 5'd0; // r0==r0
expand[12:8] = 5'd0; // Ra = r0
expand[7:6] = 2'b10;
expand[5:0] = `Bcc; // 0x38
end
/FT64_ipt.v
1,6 → 1,6
// ============================================================================
// __
// \\__/ o\ (C) 2018 Robert Finch, Waterloo
// \\__/ o\ (C) 2018-2019 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
27,13 → 27,15
`define TRUE 1'b1
`define FALSE 1'b0
`endif
//`define BYPASS 1'b1
 
module FT64_ipt(rst, clk, pkeys_i, ol_i, cti_i, cs_i, icl_i, cyc_i, stb_i, ack_o, we_i, sel_i, vadr_i, dat_i, dat_o,
cyc_o, ack_i, we_o, padr_o, exv_o, rdv_o, wrv_o, prv_o, page_fault);
module FT64_ipt(rst, clk, pkeys_i, ol_i, bte_i, cti_i, cs_i, icl_i, cyc_i, stb_i, ack_o, we_i, sel_i, vadr_i, dat_i, dat_o,
bte_o, cti_o, cyc_o, ack_i, we_o, sel_o, padr_o, exv_o, rdv_o, wrv_o, prv_o, page_fault);
input rst;
input clk;
input [63:0] pkeys_i;
input [1:0] ol_i;
input [1:0] bte_i;
input [2:0] cti_i;
input cs_i;
input icl_i;
45,9 → 47,12
input [63:0] vadr_i;
input [63:0] dat_i;
output reg [63:0] dat_o;
output reg [1:0] bte_o;
output reg [2:0] cti_o;
output reg cyc_o;
input ack_i;
output reg we_o;
output reg [7:0] sel_o;
output reg [31:0] padr_o;
output reg exv_o;
output reg rdv_o;
64,6 → 69,7
parameter S_CMP6 = 4'd6;
parameter S_WAIT1 = 4'd7;
parameter S_ACK = 4'd8;
parameter S_RESET = 4'd9;
 
integer n;
wire [9:0] pkey [0:5];
105,7 → 111,7
reg keymatch;
always @*
begin
keymatch = 1'b0;
keymatch = ol_i==2'b00;
for (n = 0; n < 6; n = n + 1)
if (pt_key==pkey[n] || pt_key==10'h0)
keymatch = 1'b1;
143,6 → 149,30
endcase
 
always @(posedge clk)
bte_o <= bte_i;
always @(posedge clk)
cti_o <= cti_i;
always @(posedge clk)
sel_o <= sel_i;
`ifdef BYPASS
always @(posedge clk)
cyc_o <= cyc_i;
always @(posedge clk)
we_o <= we_i;
always @(posedge clk)
padr_o <= vadr_i[31:0];
always @(posedge clk)
exv_o <= 1'b0;
always @(posedge clk)
rdv_o <= 1'b0;
always @(posedge clk)
wrv_o <= 1'b0;
always @(posedge clk)
prv_o <= 1'b0;
always @(posedge clk)
page_fault <= 1'b0;
`else
always @(posedge clk)
if (rst) begin
cyc_o <= 1'b0;
padr_o <= 32'hFFFC0100;
151,7 → 181,9
rdv_o <= 1'b0;
wrv_o <= 1'b0;
prv_o <= 1'b0;
pt_wr <= 1'b0;
pt_wr <= 1'b1;
pt_ad <= 1'b0;
pt_dati <= 1'b0;
upd <= 1'b0;
probe <= 1'b0;
upd_done <= 1'b0;
163,9 → 195,18
page_fault <= 1'b0;
ack_o <= 1'b0;
case(state)
// Clear page table ram on reset.
S_RESET:
begin
pt_ad <= pt_ad + 2'd1;
if (&pt_ad) begin
pt_wr <= 1'b0;
state <= S_IDLE;
end
end
S_IDLE:
if (cyc_i) begin
if (cs_i) begin
if (cs_i & stb_i) begin
ack_o <= 1'b1;
case(vadr_i[5:3])
3'd0:
202,7 → 243,7
if (ol_i==2'b0) begin
cyc_o <= 1'b1;
we_o <= we_i;
padr_o <= vadr_i;
padr_o <= vadr_i[31:0];
goto(S_ACK);
end
else begin
211,7 → 252,7
if (vadr_i[31:24]==8'hFF || vadr_i[31:24]==8'h00) begin
cyc_o <= 1'b1;
we_o <= we_i;
padr_o <= vadr_i;
padr_o <= vadr_i[31:0];
goto(S_ACK);
end
else begin
294,7 → 335,7
else begin
cyc_o <= 1'b1;
we_o <= 1'b0;
padr_o <= 64'hFFFFFFFFFFFFFFF8;
padr_o <= 32'hFFFFFFF8;
prv_o <= 1'b1;
end
goto(S_ACK);
374,7 → 415,7
else begin
cyc_o <= 1'b1;
we_o <= 1'b0;
padr_o <= 64'hFFFFFFFFFFFFFFF8;
padr_o <= 32'hFFFFFFF8;
prv_o <= 1'b1;
end
goto(S_ACK);
400,6 → 441,7
 
endcase
end
`endif
 
task goto;
input [3:0] nst;
/FT64_mpu.v
1,7 → 1,7
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2017-2018 Robert Finch, Waterloo
// \\__/ o\ (C) 2017-2019 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
71,8 → 71,8
input i26;
input i27;
input i28;
output reg [2:0] cti_o;
output reg [1:0] bte_o;
output [2:0] cti_o;
output [1:0] bte_o;
input bok_i;
output cyc_o;
output reg stb_o;
79,7 → 79,7
input ack_i;
input err_i;
output we_o;
output reg [7:0] sel_o;
output [7:0] sel_o;
output [31:0] adr_o;
output reg [63:0] dat_o;
input [63:0] dat_i;
91,6 → 91,7
wire [2:0] bte;
wire cyc,stb,we;
wire [7:0] sel;
(* mark_debug="true" *)
wire [63:0] adr;
reg [63:0] dati;
wire [63:0] dato;
115,10 → 116,6
wire sptr_o;
wire [63:0] pkeys;
 
always @(posedge clk_i)
cti_o <= cti;
always @(posedge clk_i)
bte_o <= bte;
//always @(posedge clk_i)
// cyc_o <= cyc;
always @(posedge clk_i)
125,8 → 122,6
stb_o <= stb;
//always @(posedge clk_i)
// we_o <= we;
always @(posedge clk_i)
sel_o <= sel;
//always @(posedge clk_i)
// adr_o <= adr;
always @(posedge clk_i)
243,6 → 238,7
.clk(clk_i),
.pkeys_i(pkeys),
.ol_i(ol),
.bte_i(bte),
.cti_i(cti),
.cs_i(cs_ipt),
.icl_i(icl),
254,9 → 250,12
.vadr_i(adr),
.dat_i(dato),
.dat_o(ipt_dato),
.bte_o(bte_o),
.cti_o(cti_o),
.cyc_o(cyc_o),
.ack_i(ack),
.we_o(we_o),
.sel_o(sel_o),
.padr_o(adr_o),
.exv_o(exv),
.rdv_o(rdv),
264,12 → 263,13
);
 
always @(posedge clk_i)
casez({pic_ack,pit_ack,crd_ack,cs_ipt})
4'b1???: dati <= {2{pic_dato}};
4'b01??: dati <= {2{pit_dato}};
4'b001?: dati <= crd_dato;
4'b0001: dati <= ipt_dato;
default: dati <= dat_i;
casez({pic_ack,pit_ack,crd_ack,cs_ipt,ack_i})
5'b1????: dati <= {2{pic_dato}};
5'b01???: dati <= {2{pit_dato}};
5'b001??: dati <= crd_dato;
5'b0001?: dati <= ipt_dato;
5'b00001: dati <= dat_i;
default: dati <= dati;
endcase
 
always @(posedge clk_i)
/FT64_pic.v
1,7 → 1,7
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2013-2018 Robert Finch, Waterloo
// \\__/ o\ (C) 2013-2019 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
55,6 → 55,10
// This register resets the edge sense circuitry
// indicated by the low order five bits of the input data.
//
// 0x18 - write only
// This register triggers the interrupt indicated by the low
// order five bits of the input data.
//
// 0x80 - irq control for irq #0
// 0x84 - irq control for irq #1
// bits 0 to 7 = cause code to issue
82,10 → 86,11
output [3:0] irqo, // normally connected to the processor irq
input nmii, // nmi input connected to nmi requester
output nmio, // normally connected to the nmi of cpu
output [6:0] causeo
output [7:0] causeo
);
parameter pIOAddress = 32'hFFDC_0F00;
 
reg [31:0] trig;
reg [31:0] ie; // interrupt enable register
reg rdy1;
reg [4:0] irqenc;
121,9 → 126,11
if (rst_i) begin
ie <= 32'h0;
rste <= 32'h0;
trig <= 32'h0;
end
else begin
rste <= 32'h0;
trig <= 32'h0;
if (cs & wr_i) begin
casez (adr_i[7:2])
6'd0: ;
135,6 → 142,7
ie[dat_i[4:0]] <= adr_i[2];
6'd4: es <= dat_i[31:0];
6'd5: rste[dat_i[4:0]] <= 1'b1;
6'd6: trig[dat_i[4:0]] <= 1'b1;
6'b1?????:
begin
cause[adr_i[6:2]] <= dat_i[7:0];
161,7 → 169,7
dat_o <= 32'h0000;
end
 
assign irqo = (irqenc == 5'h0) ? 4'd0 : irq[irqenc];
assign irqo = (irqenc == 5'h0) ? 4'd0 : irq[irqenc] & {4{ie[irqenc]}};
assign causeo = (irqenc == 5'h0) ? 8'd0 : cause[irqenc];
assign nmio = nmii & ie[0];
 
171,6 → 179,7
for (n = 1; n < 32; n = n + 1)
begin
ib[n] <= i[n];
if (trig[n]) iedge[n] <= 1'b1;
if (i[n] & !ib[n]) iedge[n] <= 1'b1;
if (rste[n]) iedge[n] <= 1'b0;
end
183,7 → 192,7
begin
irqenc <= 5'd0;
for (n = 31; n > 0; n = n - 1)
if (ie[n] & (es[n] ? iedge[n] : i[n])) irqenc <= n;
if ((es[n] ? iedge[n] : i[n])) irqenc <= n;
end
 
endmodule
/FT64_shift.v
1,7 → 1,7
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2016-2018 Robert Finch, Waterloo
// \\__/ o\ (C) 2016-2019 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||

powered by: WebSVN 2.1.0

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