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 |
// || |