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 61 to Rev 66
    Reverse comparison

Rev 61 → Rev 66

/FT64_ICController.v
0,0 → 1,305
// ============================================================================
// __
// \\__/ o\ (C) 2017-2019 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// FT64_ICController.v
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// ============================================================================
//
`include ".\FT64_config.vh"
`define HIGH 1'b1
`define LOW 1'b0;
 
module FT64_ICController(clk_i, asid, pc0, pc1, pc2, hit0, hit1, hit2, bstate, state,
invline, invlineAddr,
thread_en, ihitL2, selL2, L2_ld, L2_cnt, L2_adr, L2_dato, L2_nxt,
L1_selpc, L1_adr, L1_dat, L1_wr0, L1_wr1, L1_wr2, L1_en, L1_invline, icnxt, icwhich,
icl_o, cti_o, bte_o, bok_i, cyc_o, stb_o, ack_i, err_i, tlbmiss_i, exv_i, sel_o, adr_o, dat_i);
parameter ABW = 64;
parameter AMSB = ABW-1;
parameter RSTPC = 64'hFFFFFFFFFFFC0100;
input clk_i;
input [7:0] asid;
input [AMSB:0] pc0;
input [AMSB:0] pc1;
input [AMSB:0] pc2;
input hit0;
input hit1;
input hit2;
input [4:0] bstate;
(* mark_debug="true" *)
output reg [3:0] state = IDLE;
input invline;
input [71:0] invlineAddr;
input thread_en;
input ihitL2;
output reg selL2 = 1'b0;
output reg L2_ld;
output [2:0] L2_cnt;
output reg [71:0] L2_adr = RSTPC;
input [305:0] L2_dato;
output reg L2_nxt;
output L1_selpc;
output reg [71:0] L1_adr = RSTPC;
output reg [305:0] L1_dat = {2'b0,{38{8'h3D}}}; // NOP
output reg L1_wr0;
output reg L1_wr1;
output reg L1_wr2;
output reg [9:0] L1_en;
output reg L1_invline;
output reg icnxt;
output reg [1:0] icwhich;
output reg icl_o;
output reg [2:0] cti_o = 3'b000;
output reg [1:0] bte_o = 2'b00;
input bok_i;
output reg cyc_o = 1'b0;
output reg stb_o;
input ack_i;
input err_i;
input tlbmiss_i;
input exv_i;
output reg [7:0] sel_o;
output reg [71:0] adr_o;
input [63:0] dat_i;
 
parameter TRUE = 1'b1;
parameter FALSE = 1'b0;
 
reg [3:0] picstate;
`include ".\FT64_busStates.vh"
reg invline_r = 1'b0;
reg [71:0] invlineAddr_r = 72'd0;
 
wire [AMSB:0] pc0plus6 = pc0 + 8'd7;
wire [AMSB:0] pc0plus12 = pc0 + 8'd14;
 
//assign L2_ld = (state==IC_Ack) && (ack_i|err_i|tlbmiss_i|exv_i);
assign L1_selpc = (state==IDLE||state==IC_Next) && !invline_r;
 
wire clk = clk_i;
reg [2:0] iccnt;
assign L2_cnt = iccnt;
 
//BUFH uclkb (.I(clk_i), .O(clk));
 
always @(posedge clk)
begin
L1_wr0 <= FALSE;
L1_wr1 <= FALSE;
L1_wr2 <= FALSE;
L1_en <= 10'h000;
L1_invline <= FALSE;
icnxt <= FALSE;
L2_nxt <= FALSE;
if (invline) begin
invline_r <= 1'b1;
invlineAddr_r <= invlineAddr;
end
 
// Instruction cache state machine.
// On a miss first see if the instruction is in the L2 cache. No need to go to
// the BIU on an L1 miss.
// If not the machine will wait until the BIU loads the L2 cache.
 
// Capture the previous ic state, used to determine how long to wait in
// icstate #4.
picstate <= state;
case(state)
IDLE:
begin
iccnt <= 3'd0;
if (invline_r) begin
L1_adr <= {invlineAddr_r[71:5],5'b0};
L1_invline <= TRUE;
invline_r <= 1'b0;
end
// If the bus unit is busy doing an update involving L1_adr or L2_adr
// we have to wait.
else begin
if (!hit0) begin
L1_adr <= {asid,pc0[AMSB:5],5'h0};
L1_invline <= TRUE;
icwhich <= 2'b00;
state <= IC2;
end
else if (!hit1 && `WAYS > 1) begin
if (thread_en) begin
L1_adr <= {asid,pc1[AMSB:5],5'h0};
end
else begin
L1_adr <= {asid,pc0plus6[AMSB:5],5'h0};
end
L1_invline <= TRUE;
icwhich <= 2'b01;
state <= IC2;
end
else if (!hit2 && `WAYS > 2) begin
if (thread_en) begin
L1_adr <= {asid,pc2[AMSB:5],5'h0};
end
else begin
L1_adr <= {asid,pc0plus12[AMSB:5],5'h0};
end
L1_invline <= TRUE;
icwhich <= 2'b10;
state <= IC2;
end
end
end
IC2: state <= IC3;
IC3: state <= IC3a;
IC3a: state <= IC_WaitL2;
// If data was in the L2 cache already there's no need to wait on the
// BIU to retrieve data. It can be determined if the hit signal was
// already active when this state was entered in which case waiting
// will do no good.
// The IC machine will stall in this state until the BIU has loaded the
// L2 cache.
IC_WaitL2:
if (ihitL2 && picstate==IC3a) begin
L1_en <= 10'h3FF;
L1_wr0 <= TRUE;
L1_wr1 <= TRUE && `WAYS > 1;
L1_wr2 <= TRUE && `WAYS > 2;
// L1_adr <= L2_adr;
// L1_dati is loaded dring an L2 icache load operation
// if (picstate==IC3a)
L1_dat <= L2_dato;
state <= IC5;
end
else begin
if (bstate == B_WaitIC)
state <= IC_Access;
end
/*
else if (state!=IC_Nack)
;
else begin
L1_en <= 10'h3FF;
L1_wr0 <= TRUE;
L1_wr1 <= TRUE && `WAYS > 1;
L1_wr2 <= TRUE && `WAYS > 2;
// L1_adr <= L2_adr;
// L1_dati set below while loading cache line
//L1_dati <= L2_dato;
state <= IC5;
end
*/
IC5: state <= IC6;
IC6: state <= IC7;
IC7: state <= IC_Next;
IC_Next:
begin
state <= IDLE;
icnxt <= TRUE;
end
IC_Access:
begin
iccnt <= 3'd0;
icl_o <= `HIGH;
cti_o <= 3'b001;
bte_o <= 2'b00;
cyc_o <= `HIGH;
stb_o <= `HIGH;
sel_o <= 8'hFF;
adr_o <= {L1_adr[AMSB:5],5'b0};
L2_adr <= L1_adr;
L2_adr[4:0] <= 5'd0;
selL2 <= TRUE;
L2_ld <= TRUE;
state <= IC_Ack;
end
IC_Ack:
if (ack_i|err_i|tlbmiss_i|exv_i) begin
L2_ld <= TRUE;
if (!bok_i) begin
stb_o <= `LOW;
adr_o[AMSB:3] <= adr_o[AMSB:3] + 2'd1;
state <= IC_Nack2;
end
if (tlbmiss_i) begin
L1_dat[305:304] <= 2'd1;
L1_dat[303:0] <= {38{8'h3D}}; // NOP
nack();
end
else if (exv_i) begin
L1_dat[305:304] <= 2'd2;
L1_dat[303:0] <= {38{8'h3D}}; // NOP
nack();
end
else if (err_i) begin
L1_dat[305:304] <= 2'd3;
L1_dat[303:0] <= {38{8'h3D}}; // NOP
nack();
end
else
case(iccnt)
3'd0: L1_dat[63:0] <= dat_i;
3'd1: L1_dat[127:64] <= dat_i;
3'd2: L1_dat[191:128] <= dat_i;
3'd3: L1_dat[255:192] <= dat_i;
3'd4: L1_dat[305:256] <= {2'b00,dat_i[47:0]};
default: L1_dat <= L1_dat;
endcase
iccnt <= iccnt + 3'd1;
if (iccnt==3'd3)
cti_o <= 3'b111;
if (iccnt>=3'd4)
nack();
end
IC_Nack2:
if (~ack_i) begin
stb_o <= `HIGH;
state <= IC_Ack;
end
IC_Nack:
begin
iccnt <= iccnt + 3'd1;
L2_ld <= FALSE;
selL2 <= FALSE;
if (~ack_i) begin
//icl_ctr <= icl_ctr + 40'd1;
state <= IDLE;
L2_nxt <= TRUE;
end
end
default:
begin
state <= IDLE;
end
endcase
end
 
task nack;
begin
icl_o <= `LOW;
cti_o <= 3'b000;
cyc_o <= `LOW;
stb_o <= `LOW;
L1_en <= 10'h3FF;
L1_wr0 <= TRUE;
L1_wr1 <= TRUE && `WAYS > 1;
L1_wr2 <= TRUE && `WAYS > 2;
state <= IC_Nack;
end
endtask
 
endmodule
/FT64_alu.v
25,10 → 25,9
`include "FT64_defines.vh"
`include "FT64_config.vh"
 
module FT64_alu(rst, clk, ld, abort, instr, sz, tlb, store, a, b, c, t, pc, Ra, tgt, tgt2, ven, vm,
module FT64_alu(rst, clk, ld, abort, instr, sz, store, a, b, c, t, pc, Ra, tgt, tgt2, ven, vm,
csr, o, ob, done, idle, excen, exc, thrd, ptrmask, state, mem, shift,
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
ol, dl
`ifdef SUPPORT_BBMS
, pb, cbl, cbu, ro, dbl, dbu, sbl, sbu, en
`endif
47,7 → 46,6
input abort;
input [47:0] instr;
input [2:0] sz;
input tlb;
input store;
input [63:0] a;
input [63:0] b;
73,19 → 71,6
input shift;
input [1:0] ol;
input [1:0] dl;
input [7:0] ASID;
input icl_i;
input cyc_i;
input we_i;
input [ABW-1:0] vadr_i;
output cyc_o;
output we_o;
output [ABW-1:0] padr_o;
output uncached;
output tlb_miss;
output wrv_o;
output rdv_o;
output exv_o;
`ifdef SUPPORT_BBMS
input [63:0] pb;
input [63:0] cbl;
282,48 → 267,6
default: shift10 <= shift9;
endcase
 
wire tlb_done, tlb_idle;
wire [DBW-1:0] tlbo;
 
`ifdef SUPPORT_TLB
FT64_TLB utlb1 (
.rst(rst),
.clk(clk),
.ld(ld & tlb),
.done(tlb_done),
.idle(tlb_idle),
.ol(ol),
.ASID(ASID),
.op(instr[25:22]),
.regno(instr[21:18]),
.dati(a),
.dato(tlbo),
.uncached(uncached),
.icl_i(icl_i),
.cyc_i(cyc_i),
.we_i(we_i),
.vadr_i(vadr_i),
.cyc_o(cyc_o),
.we_o(we_o),
.padr_o(padr_o),
.TLBMiss(tlb_miss),
.wrv_o(wrv_o),
.rdv_o(rdv_o),
.exv_o(exv_o),
.HTLBVirtPageo()
);
`else
assign tlbo = 64'hDEADDEADDEADDEAD;
assign uncached = 1'b0;
assign padr_o = vadr_i;
assign cyc_o = cyc_i;
assign we_o = we_i;
assign tlb_miss = 1'b0;
assign wrv_o = 1'b0;
assign rdv_o = 1'b0;
assign exv_o = 1'b0;
`endif
 
FT64_bitfield #(DBW) ubf1
(
.inst(instr),
1047,9 → 990,24
`ADD:
`ifdef SIMD
case(sz)
3'd0,3'd4:
3'd0:
begin
o[7:0] = a[7:0] + b[7:0];
o[63:8] = {56{o[7]}};
end
3'd1:
begin
o[15:0] = a[15:0] + b[15:0];
o[63:16] = {48{o[15]}};
end
3'd2:
begin
o[31:0] = a[31:0] + b[31:0];
o[63:32] = {32{o[31]}};
end
3'd4:
begin
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];
1058,7 → 1016,7
o[55:48] = a[55:48] + b[55:48];
o[63:56] = a[63:56] + b[63:56];
end
3'd1,3'd5:
3'd5:
begin
o[15:0] = a[15:0] + b[15:0];
o[31:16] = a[31:16] + b[31:16];
1065,7 → 1023,7
o[47:32] = a[47:32] + b[47:32];
o[63:48] = a[63:48] + b[63:48];
end
3'd2,3'd6:
3'd6:
begin
o[31:0] = a[31:0] + b[31:0];
o[63:32] = a[63:32] + b[63:32];
1078,7 → 1036,6
`else
o = a + b;
`endif
// If the operation is SIMD the target register must be passed in arg T.
`SUB:
`ifdef SIMD
case(sz)
1085,8 → 1042,18
3'd0:
begin
o[7:0] = a[7:0] - b[7:0];
o[63:8] = t[63:8];
o[63:8] = {56{o[7]}};
end
3'd1:
begin
o[15:0] = a[15:0] - b[15:0];
o[63:16] = {48{o[15]}};
end
3'd2:
begin
o[31:0] = a[31:0] - b[31:0];
o[63:32] = {31{o[31]}};
end
3'd4:
begin
o[7:0] = a[7:0] - b[7:0];
1098,7 → 1065,7
o[55:48] = a[55:48] - b[55:48];
o[63:56] = a[63:56] - b[63:56];
end
3'd1,3'd5:
3'd5:
begin
o[15:0] = a[15:0] - b[15:0];
o[31:16] = a[31:16] - b[31:16];
1105,14 → 1072,14
o[47:32] = a[47:32] - b[47:32];
o[63:48] = a[63:48] - b[63:48];
end
3'd2,3'd6:
3'd6:
begin
o[31:0] = a[31:0] - b[31:0];
o[63:32] = a[63:32] - b[63:32];
end
default:
default:
begin
o[63:0] = a - b;
o = a - b;
end
endcase
`else
1160,25 → 1127,10
`MIN:
`ifdef SIMD
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 = BIG ? ($signed(a) < $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
end
3'd0: o = BIG ? ($signed(a[7:0]) < $signed(b[7:0]) ? {{56{a[7]}},a[7:0]} : {{56{b[7]}},b[7:0]}) : 64'hCCCCCCCCCCCCCCCC;
3'd1: o = BIG ? ($signed(a[15:0]) < $signed(b[15:0]) ? {{48{a[15]}},a[15:0]} : {{48{b[15]}},b[15:0]}) : 64'hCCCCCCCCCCCCCCCC;
3'd2: o = BIG ? ($signed(a[31:0]) < $signed(b[31:0]) ? {{32{a[31]}},a[31:0]} : {{32{b[31]}},b[31:0]}) : 64'hCCCCCCCCCCCCCCCC;
3'd3: o = BIG ? ($signed(a) < $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
3'd4:
begin
o[7:0] = BIG ? ($signed(a[7:0]) < $signed(b[7:0]) ? a[7:0] : b[7:0]) : 8'hCC;
1213,7 → 1165,11
`MAX:
`ifdef SIMD
case(sz)
3'd0,3'd4:
3'd0: o = BIG ? ($signed(a[7:0]) > $signed(b[7:0]) ? {{56{a[7]}},a[7:0]} : {{56{b[7]}},b[7:0]}) : 64'hCCCCCCCCCCCCCCCC;
3'd1: o = BIG ? ($signed(a[15:0]) > $signed(b[15:0]) ? {{48{a[15]}},a[15:0]} : {{48{b[15]}},b[15:0]}) : 64'hCCCCCCCCCCCCCCCC;
3'd2: o = BIG ? ($signed(a[31:0]) > $signed(b[31:0]) ? {{32{a[31]}},a[31:0]} : {{32{b[31]}},b[31:0]}) : 64'hCCCCCCCCCCCCCCCC;
3'd3: o = BIG ? ($signed(a) > $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
3'd4:
begin
o[7:0] = BIG ? ($signed(a[7:0]) > $signed(b[7:0]) ? a[7:0] : b[7:0]) : 64'hCCCCCCCCCCCCCCCC;
o[15:8] = BIG ? ($signed(a[15:8]) > $signed(b[15:8]) ? a[15:8] : b[15:8]) : 64'hCCCCCCCCCCCCCCCC;
1224,7 → 1180,7
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:
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;
1231,13 → 1187,13
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:
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:
begin
3'd7:
begin
o[63:0] = BIG ? ($signed(a) > $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
end
endcase
1264,7 → 1220,6
`RTSNE: o = as!=bs;
endcase
*/
`TLB: o = BIG ? tlbo : 64'hDEADDEADDEADDEAD;
default: o[63:0] = 64'hDEADDEADDEADDEAD;
endcase
`MEMNDX:
1398,25 → 1353,25
end
endcase
`PUSHC:
begin
usa = a - 4'd8;
o = {pb[50:0],BASE_SHIFT} + usa;
end
begin
usa = a - 4'd8;
o = {pb[50:0],BASE_SHIFT} + usa;
end
`LWR,`SWC,`CAS,`CACHE:
begin
usa = a + b;
o = {pb[50:0],BASE_SHIFT} + usa;
end
begin
usa = a + b;
o = {pb[50:0],BASE_SHIFT} + usa;
end
`LV,`SV:
begin
usa = a + b + {ven,3'b0};
o = {pb[50:0],BASE_SHIFT} + usa;
end
begin
usa = a + b + {ven,3'b0};
o = {pb[50:0],BASE_SHIFT} + usa;
end
`CSRRW:
case(instr[27:18])
10'h044: o = BIG ? (csr | {39'd0,thrd,24'h0}) : 64'hDDDDDDDDDDDDDDDD;
default: o = BIG ? csr : 64'hDDDDDDDDDDDDDDDD;
endcase
case(instr[27:18])
10'h044: o = BIG ? (csr | {39'd0,thrd,24'h0}) : 64'hDDDDDDDDDDDDDDDD;
default: o = BIG ? csr : 64'hDDDDDDDDDDDDDDDD;
endcase
`BITFIELD: o = BIG ? bfout : 64'hCCCCCCCCCCCCCCCC;
default: o = 64'hDEADDEADDEADDEAD;
endcase
1510,8 → 1465,6
done <= sao_done;
else if (shift)
done <= adrDone;
else if (tlb & BIG)
done <= tlb_done;
else
done <= TRUE;
end
1535,8 → 1488,6
idle <= sao_idle;
else if (shift)
idle <= adrIdle;
else if (tlb & BIG)
idle <= tlb_idle;
else
idle <= TRUE;
end
1664,11 → 1615,11
exc <= `FLT_WRV;
else
`endif
casez(b[2:0])
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
casez(b[2:0])
3'b100: exc <= (o[2:0]!=3'b0) ? `FLT_NONE : `FLT_NONE; // LW / SW
3'b?10: exc <= (o[1:0]!=2'b0) ? `FLT_NONE : `FLT_NONE; // LH / LHU / SH
default: exc <= o[ 0] ? `FLT_NONE : `FLT_NONE; // LC / LCU / SC
endcase
end
`LWR,`SWC,`CAS,`CACHE:
begin
1713,24 → 1664,24
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[63:56]) == $signed(b[63:56]),
7'h0,$signed(a[55:48]) == $signed(b[55:48]),
7'h0,$signed(a[47:40]) == $signed(b[47:40]),
7'h0,$signed(a[39:32]) == $signed(b[39:32]),
7'h0,$signed(a[31:24]) == $signed(b[31:24]),
7'h0,$signed(a[23:16]) == $signed(b[23:16]),
7'h0,$signed(a[15:8]) == $signed(b[15:8]),
7'h0,$signed(a[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])
7'h0,$signed(a[7:0]) == $signed(b[7:0])
};
3'd5: o[63:0] = {
15'h0,$signed(a[15:0]) == $signed(b[15:0]),
15'h0,$signed(a[63:48]) == $signed(b[63:48]),
15'h0,$signed(a[47:32]) == $signed(b[47:32]),
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])
15'h0,$signed(a[15:0]) == $signed(b[15:0])
};
3'd6: o[63:0] = {
31'h0,$signed(a[31:0]) == $signed(b[31:0]),
31'h0,$signed(a[63:32]) == $signed(b[63:32])
31'h0,$signed(a[63:32]) == $signed(b[63:32]),
31'h0,$signed(a[31:0]) == $signed(b[31:0])
};
3'd7: o[63:0] = $signed(a[63:0]) == $signed(b[63:0]);
endcase
1754,24 → 1705,24
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[63:56]) < $signed(b[63:56]),
7'h0,$signed(a[55:48]) < $signed(b[55:48]),
7'h0,$signed(a[47:40]) < $signed(b[47:40]),
7'h0,$signed(a[39:32]) < $signed(b[39:32]),
7'h0,$signed(a[31:24]) < $signed(b[31:24]),
7'h0,$signed(a[23:16]) < $signed(b[23:16]),
7'h0,$signed(a[15:8]) < $signed(b[15:8]),
7'h0,$signed(a[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])
7'h0,$signed(a[7:0]) < $signed(b[7:0])
};
3'd5: o[63:0] = {
15'h0,$signed(a[15:0]) < $signed(b[15:0]),
15'h0,$signed(a[63:48]) < $signed(b[63:48]),
15'h0,$signed(a[47:32]) < $signed(b[47:32]),
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])
15'h0,$signed(a[15:0]) < $signed(b[15:0])
};
3'd6: o[63:0] = {
31'h0,$signed(a[31:0]) < $signed(b[31:0]),
31'h0,$signed(a[63:32]) < $signed(b[63:32])
31'h0,$signed(a[63:32]) < $signed(b[63:32]),
31'h0,$signed(a[31:0]) < $signed(b[31:0])
};
3'd7: o[63:0] = $signed(a[63:0]) < $signed(b[63:0]);
endcase
1795,24 → 1746,24
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[63:56]) <= $signed(b[63:56]),
7'h0,$signed(a[55:48]) <= $signed(b[55:48]),
7'h0,$signed(a[47:40]) <= $signed(b[47:40]),
7'h0,$signed(a[39:32]) <= $signed(b[39:32]),
7'h0,$signed(a[31:24]) <= $signed(b[31:24]),
7'h0,$signed(a[23:16]) <= $signed(b[23:16]),
7'h0,$signed(a[15:8]) <= $signed(b[15:8]),
7'h0,$signed(a[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])
7'h0,$signed(a[7:0]) <= $signed(b[7:0])
};
3'd5: o[63:0] = {
15'h0,$signed(a[15:0]) <= $signed(b[15:0]),
15'h0,$signed(a[63:48]) <= $signed(b[63:48]),
15'h0,$signed(a[47:32]) <= $signed(b[47:32]),
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])
15'h0,$signed(a[15:0]) <= $signed(b[15:0])
};
3'd6: o[63:0] = {
31'h0,$signed(a[31:0]) <= $signed(b[31:0]),
31'h0,$signed(a[63:32]) <= $signed(b[63:32])
31'h0,$signed(a[63:32]) <= $signed(b[63:32]),
31'h0,$signed(a[31:0]) <= $signed(b[31:0])
};
3'd7: o[63:0] = $signed(a[63:0]) <= $signed(b[63:0]);
endcase
1831,26 → 1782,29
begin
`ifdef SIMD
case(sz[2:0])
3'd4,3'd0: o = {
7'h0,(a[7:0]) < (b[7:0]),
7'h0,(a[15:8]) < (b[15:8]),
7'h0,(a[23:16]) < (b[23:16]),
7'h0,(a[31:24]) < (b[31:24]),
7'h0,(a[39:32]) < (b[39:32]),
7'h0,(a[47:40]) < (b[47:40]),
7'h0,(a[55:48]) < (b[55:48]),
7'h0,(a[63:56]) < (b[63:56])
};
3'd5,3'd1: o = {
15'h0,(a[15:0]) < (b[15:0]),
15'h0,(a[31:16]) < (b[31:16]),
15'h0,(a[47:32]) < (b[47:32]),
15'h0,(a[63:48]) < (b[63:48])
};
3'd6,3'd2: o = {
31'h0,(a[31:0]) < (b[31:0]),
31'h0,(a[63:32]) < (b[63:32])
};
3'd0: o = (a[7:0]) < (b[7:0]);
3'd1: o = (a[15:0]) < (b[15:0]);
3'd2: o = (a[31:0]) < (b[31:0]);
3'd4: o = {
7'h0,(a[63:56]) < (b[63:56]),
7'h0,(a[55:48]) < (b[55:48]),
7'h0,(a[47:40]) < (b[47:40]),
7'h0,(a[39:32]) < (b[39:32]),
7'h0,(a[31:24]) < (b[31:24]),
7'h0,(a[23:16]) < (b[23:16]),
7'h0,(a[15:8]) < (b[15:8]),
7'h0,(a[7:0]) < (b[7:0])
};
3'd5: o = {
15'h0,(a[63:48]) < (b[63:48]),
15'h0,(a[47:32]) < (b[47:32]),
15'h0,(a[31:16]) < (b[31:16]),
15'h0,(a[15:0]) < (b[15:0])
};
3'd6: o = {
31'h0,(a[63:32]) < (b[63:32]),
31'h0,(a[31:0]) < (b[31:0])
};
3'd7,3'd3: o = (a[63:0]) < (b[63:0]);
endcase
`else
1868,31 → 1822,30
begin
`ifdef SIMD
case(sz[2:0])
3'd0: o[63:0] = (a[7:0]) <= (b[7:0]);
3'd1: o[63:0] = (a[15:0]) <= (b[15:0]);
3'd2: o[63:0] = (a[31:0]) <= (b[31:0]);
3'd3: o[63:0] = (a) <= (b);
3'd4: o[63:0] = {
7'h0,(a[7:0]) <= (b[7:0]),
7'h0,(a[15:8]) <= (b[15:8]),
7'h0,(a[23:16]) <= (b[23:16]),
7'h0,(a[31:24]) <= (b[31:24]),
7'h0,(a[39:32]) <= (b[39:32]),
7'h0,(a[47:40]) <= (b[47:40]),
7'h0,(a[55:48]) <= (b[55:48]),
7'h0,(a[63:56]) <= (b[63:56])
};
3'd5: o[63:0] = {
15'h0,(a[15:0]) <= (b[15:0]),
15'h0,(a[31:16]) <= (b[31:16]),
15'h0,(a[47:32]) <= (b[47:32]),
15'h0,(a[63:48]) <= (b[63:48])
};
3'd6: o[63:0] = {
31'h0,(a[31:0]) <= (b[31:0]),
31'h0,(a[63:32]) <= (b[63:32])
};
3'd7: o[63:0] = (a[63:0]) <= (b[63:0]);
3'd0: o = (a[7:0]) <= (b[7:0]);
3'd1: o = (a[15:0]) <= (b[15:0]);
3'd2: o = (a[31:0]) <= (b[31:0]);
3'd4: o = {
7'h0,(a[63:56]) <= (b[63:56]),
7'h0,(a[55:48]) <= (b[55:48]),
7'h0,(a[47:40]) <= (b[47:40]),
7'h0,(a[39:32]) <= (b[39:32]),
7'h0,(a[31:24]) <= (b[31:24]),
7'h0,(a[23:16]) <= (b[23:16]),
7'h0,(a[15:8]) <= (b[15:8]),
7'h0,(a[7:0]) <= (b[7:0])
};
3'd5: o = {
15'h0,(a[63:48]) <= (b[63:48]),
15'h0,(a[47:32]) <= (b[47:32]),
15'h0,(a[31:16]) <= (b[31:16]),
15'h0,(a[15:0]) <= (b[15:0])
};
3'd6: o = {
31'h0,(a[63:32]) <= (b[63:32]),
31'h0,(a[31:0]) <= (b[31:0])
};
3'd7,3'd3: o = (a[63:0]) <= (b[63:0]);
endcase
`else
o[63:0] = (a[63:0]) <= (b[63:0]);
/FT64_busStates.vh
0,0 → 1,42
parameter BIDLE = 5'd0;
parameter B_StoreAck = 5'd1;
parameter B_DCacheLoadStart = 5'd2;
parameter B_DCacheLoadStb = 5'd3;
parameter B_DCacheLoadWait = 5'd4;
parameter B_DCacheLoadResetBusy = 5'd6;
parameter B8 = 5'd8;
parameter B11 = 5'd11;
parameter B_RMWAck = 5'd12;
parameter B_DLoadAck = 5'd13;
parameter B14 = 5'd14;
parameter B15 = 5'd15;
parameter B16 = 5'd16;
parameter B17 = 5'd17;
parameter B18 = 5'd18;
parameter B_LSNAck = 5'd19;
parameter B2a = 5'd20;
parameter B2b = 5'd21;
parameter B2c = 5'd22;
parameter B_DCacheLoadAck = 5'd23;
parameter B20 = 5'd24;
parameter B21 = 5'd25;
parameter B_WaitSeg = 5'd29;
parameter B_DLoadNack = 5'd30;
parameter B_WaitIC = 5'd31;
 
parameter IDLE = 4'd0;
parameter IC1 = 4'd1;
parameter IC2 = 4'd2;
parameter IC3 = 4'd3;
parameter IC_WaitL2 = 4'd4;
parameter IC5 = 4'd5;
parameter IC6 = 4'd6;
parameter IC7 = 4'd7;
parameter IC_Next = 4'd8;
parameter IC9 = 4'd9;
parameter IC10 = 4'd10;
parameter IC3a = 4'd11;
parameter IC_Access = 4'd12;
parameter IC_Ack = 4'd13;
parameter IC_Nack = 4'd14;
parameter IC_Nack2 = 4'd15;
/FT64_dcache.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
// ||
31,10 → 31,10
input dce; // data cache enable
input wclk;
input wr;
input [7:0] sel;
input [31:0] sel;
input [37:0] wadr;
output whit;
input [63:0] i;
input [255:0] i;
input [255:0] li; // line input
input rclk;
input [2:0] rdsize;
69,7 → 69,7
(
.wclk(wclk),
.dce(dce),
.wr(wr && wadr[4:3]==2'b11),
.wr(wr),
.wadr(wadr),
.rclk(rclk),
.radr(radr),
103,9 → 103,9
input rst;
input clka;
input ena;
input [7:0] wea;
input [31:0] wea;
input [13:0] addra;
input [63:0] dina;
input [255:0] dina;
input clkb;
input enb;
input [13:0] addrb;
126,25 → 126,11
 
genvar g;
generate begin
for (g = 0; g < 4; g = g + 1)
for (g = 0; g < 32; g = g + 1)
always @(posedge clka)
begin
if (ena & wea[0] & addra[4:3]==g) mem[addra[13:5]][g*64+7:g*64] <= dina[7:0];
if (ena & wea[1] & addra[4:3]==g) mem[addra[13:5]][g*64+15:g*64+8] <= dina[15:8];
if (ena & wea[2] & addra[4:3]==g) mem[addra[13:5]][g*64+23:g*64+16] <= dina[23:16];
if (ena & wea[3] & addra[4:3]==g) mem[addra[13:5]][g*64+31:g*64+24] <= dina[31:24];
if (ena & wea[4] & addra[4:3]==g) mem[addra[13:5]][g*64+39:g*64+32] <= dina[39:32];
if (ena & wea[5] & addra[4:3]==g) mem[addra[13:5]][g*64+47:g*64+40] <= dina[47:40];
if (ena & wea[6] & addra[4:3]==g) mem[addra[13:5]][g*64+55:g*64+48] <= dina[55:48];
if (ena & wea[7] & addra[4:3]==g) mem[addra[13:5]][g*64+63:g*64+56] <= dina[63:56];
if (ena & wea[0] & addra[4:3]==g) valid[addra[13:5]][g*8] <= 1'b1;
if (ena & wea[1] & addra[4:3]==g) valid[addra[13:5]][g*8+1] <= 1'b1;
if (ena & wea[2] & addra[4:3]==g) valid[addra[13:5]][g*8+2] <= 1'b1;
if (ena & wea[3] & addra[4:3]==g) valid[addra[13:5]][g*8+3] <= 1'b1;
if (ena & wea[4] & addra[4:3]==g) valid[addra[13:5]][g*8+4] <= 1'b1;
if (ena & wea[5] & addra[4:3]==g) valid[addra[13:5]][g*8+5] <= 1'b1;
if (ena & wea[6] & addra[4:3]==g) valid[addra[13:5]][g*8+6] <= 1'b1;
if (ena & wea[7] & addra[4:3]==g) valid[addra[13:5]][g*8+7] <= 1'b1;
if (ena & wea[g]) mem[addra[13:5]][g*8+7:g*8] <= dina[g*8+7:g*8];
if (ena & wea[g]) valid[addra[13:5]][g] <= 1'b1;
end
end
endgenerate
/FT64_defines.vh
353,7 → 353,7
`define CSR_CAS 10'h02C
`define CSR_TVEC 10'b00000110???
`define CSR_IM_STACK 10'h040
`define CSR_OL_STACK 10'h041
`define CSR_ODL_STACK 10'h041
`define CSR_PL_STACK 10'h042
`define CSR_RS_STACK 10'h043
`define CSR_STATUS 10'h044
461,6 → 461,7
 
`define DRAMSLOT_AVAIL 3'b000
`define DRAMSLOT_BUSY 3'b001
`define DRAMSLOT_BUSY2 3'b010
`define DRAMSLOT_REQBUS 3'b101
`define DRAMSLOT_HASBUS 3'b110
`define DRAMREQ_READY 3'b111
/FT64_icache.v
375,23 → 375,26
reg [9:0] en1, en2;
reg invline1, invline2;
 
wire iclk;
BUFH ucb1 (.I(clk), .O(iclk));
 
// Must update the cache memory on the cycle after a write to the tag memmory.
// Otherwise lineno won't be valid. Tag memory takes two clock cycles to update.
always @(posedge clk)
always @(posedge iclk)
wr1 <= wr;
always @(posedge clk)
always @(posedge iclk)
wr2 <= wr1;
always @(posedge clk)
always @(posedge iclk)
i1 <= i[305:0];
always @(posedge clk)
always @(posedge iclk)
i2 <= i1;
always @(posedge clk)
always @(posedge iclk)
en1 <= en;
always @(posedge clk)
always @(posedge iclk)
en2 <= en1;
always @(posedge clk)
always @(posedge iclk)
invline1 <= invline;
always @(posedge clk)
always @(posedge iclk)
invline2 <= invline1;
 
generate begin : tags
400,7 → 403,7
FT64_L1_icache_mem #(.pLines(pLines)) u1
(
.rst(rst),
.clk(clk),
.clk(iclk),
.wr(wr1),
.en(en1),
.i(i1),
414,7 → 417,7
FT64_L1_icache_cmptag4way #(.pLines(pLines)) u3
(
.rst(rst),
.clk(clk),
.clk(iclk),
.nxt(nxt),
.wr(wr),
.adr(adr),
427,7 → 430,7
FT64_L1_icache_mem u1
(
.rst(rst),
.clk(clk),
.clk(iclk),
.wr(wr2),
.en(en2),
.i(i2),
441,7 → 444,7
FT64_L1_icache_camtag u2
(
.rst(rst),
.clk(clk),
.clk(iclk),
.nxt(nxt),
.wlineno(wlineno),
.wadr(wadr),
538,7 → 541,7
// address bit 4).
// -----------------------------------------------------------------------------
 
module FT64_L2_icache(rst, clk, nxt, wr, wr_ack, rd_ack, xsel, adr, cnt, exv_i, i, err_i, o, hit, invall, invline);
module FT64_L2_icache(rst, clk, nxt, wr, adr, cnt, exv_i, i, err_i, o, hit, invall, invline);
parameter CAMTAGS = 1'b0; // 32 way
parameter FOURWAY = 1'b1;
parameter AMSB = 63;
546,9 → 549,6
input clk;
input nxt;
input wr;
output wr_ack;
output rd_ack;
input xsel;
input [AMSB+8:0] adr;
input [2:0] cnt;
input exv_i;
575,7 → 575,7
always @(posedge clk)
wr2 <= wr1;
always @(posedge clk)
sel1 <= {xsel,adr[4:3]};
sel1 <= cnt;
always @(posedge clk)
sel2 <= sel1;
always @(posedge clk)
585,20 → 585,7
always @(posedge clk)
f2 <= f1;
reg [3:0] rdackx;
always @(posedge clk)
if (rst)
rdackx <= 4'b0;
else begin
if (last_adr != adr || wr || wr1 || wr2)
rdackx <= 4'b0;
else
rdackx <= {rdackx,~(wr|wr1|wr2)};
end
 
assign rd_ack = rdackx[3] & ~(last_adr!=adr || wr || wr1 || wr2);
 
always @(posedge clk)
i1 <= i;
always @(posedge clk)
i2 <= i1;
657,7 → 644,6
endgenerate
 
assign hit = taghit & lv;
assign wr_ack = wr2;
 
endmodule
 
/FT64_ipt.v
27,7 → 27,7
`define TRUE 1'b1
`define FALSE 1'b0
`endif
//`define BYPASS 1'b1
`define BYPASS 1'b1
 
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);
156,6 → 156,12
sel_o <= sel_i;
`ifdef BYPASS
always @(posedge clk)
pt_wr <= 1'b0;
always @(posedge clk)
pt_ad <= 16'h0;
always @(posedge clk)
pt_dati <= 42'h0;
always @(posedge clk)
cyc_o <= cyc_i;
always @(posedge clk)
we_o <= we_i;
171,6 → 177,8
prv_o <= 1'b0;
always @(posedge clk)
page_fault <= 1'b0;
always @(posedge clk)
ack_o <= 1'b0;
`else
always @(posedge clk)
if (rst) begin
428,7 → 436,8
 
// Wait a clock cycle for a page fault to register.
S_WAIT1:
goto(S_IDLE);
if (!ack_i)
goto(S_IDLE);
S_ACK:
if (ack_i) begin
/FT64_pic.v
90,6 → 90,7
);
parameter pIOAddress = 32'hFFDC_0F00;
 
wire clk;
reg [31:0] trig;
reg [31:0] ie; // interrupt enable register
reg rdy1;
117,12 → 118,15
wire cs = cyc_i && stb_i && adr_i[31:8]==pIOAddress[31:8];
assign vol_o = cs;
 
always @(posedge clk_i)
assign clk = clk_i;
//BUFH ucb1 (.I(clk_i), .O(clk));
 
always @(posedge clk)
rdy1 <= cs;
assign ack_o = cs ? (wr_i ? 1'b1 : rdy1) : 1'b0;
 
// write registers
always @(posedge clk_i)
always @(posedge clk)
if (rst_i) begin
ie <= 32'h0;
rste <= 32'h0;
155,7 → 159,7
end
 
// read registers
always @(posedge clk_i)
always @(posedge clk)
begin
if (irqenc!=5'd0)
$display("PIC: %d",irqenc);
174,7 → 178,7
assign nmio = nmii & ie[0];
 
// Edge detect circuit
always @(posedge clk_i)
always @(posedge clk)
begin
for (n = 1; n < 32; n = n + 1)
begin
188,7 → 192,7
// irq requests are latched on every rising clock edge to prevent
// misreads
// nmi is not encoded
always @(posedge clk_i)
always @(posedge clk)
begin
irqenc <= 5'd0;
for (n = 31; n > 0; n = n - 1)

powered by: WebSVN 2.1.0

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