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
    from Rev 55 to Rev 56
    Reverse comparison

Rev 55 → Rev 56

/FT64v5/rtl/common/FT64_InsLength.v
0,0 → 1,44
// ============================================================================
// __
// \\__/ o\ (C) 2018 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// FT64_InsLength.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/>.
//
// Computes the length of an instruction.
// There are also other places in code where the length is determined
// without the use of this module.
// ============================================================================
//
`include "FT64_defines.vh"
 
module FT64_InsLength(ins, len);
input [47:0] ins;
output reg [2:0] len;
 
always @*
if (ins[`INSTRUCTION_OP]==`CMPRSSD)
len <= 3'd2;
else
case(ins[7:6])
2'd0: len <= 3'd4;
2'd1: len <= 3'd6;
default: len <= 3'd2;
endcase
 
endmodule
/FT64v5/rtl/common/FT64_idecoder.v
737,6 → 737,7
`CAS: IsRFW = TRUE;
`AMO: IsRFW = TRUE;
`CSRRW: IsRFW = TRUE;
`AUIPC: IsRFW = TRUE;
`LUI: IsRFW = TRUE;
default: IsRFW = FALSE;
endcase
/FT64v5/rtl/twoway/FT64.v
1727,7 → 1727,7
`RET: fnRt = {rgs[thrd],1'b0,isn[`INSTRUCTION_RA]};
`LV: fnRt = {vqei,1'b1,isn[`INSTRUCTION_RB]};
`AMO: fnRt = isn[31] ? {rgs[thrd],1'b0,isn[`INSTRUCTION_RB]} : {rgs[thrd],1'b0,isn[`INSTRUCTION_RC]};
`LUI: fnRt = {rgs[thrd],1'b0,isn[`INSTRUCTION_RA]};
`AUIPC,`LUI: fnRt = {rgs[thrd],1'b0,isn[`INSTRUCTION_RA]};
default: fnRt = {rgs[thrd],1'b0,isn[`INSTRUCTION_RB]};
endcase
endfunction
1951,7 → 1951,7
`RET: fnRt = {rgs,1'b0,isn[`INSTRUCTION_RA]};
`LV: fnRt = {vqei,1'b1,isn[`INSTRUCTION_RB]};
`AMO: fnRt = isn[31] ? {rgs,1'b0,isn[`INSTRUCTION_RB]} : {rgs,1'b0,isn[`INSTRUCTION_RC]};
`LUI: fnRt = {rgs,1'b0,isn[`INSTRUCTION_RA]};
`AUIPC,`LUI: fnRt = {rgs,1'b0,isn[`INSTRUCTION_RA]};
default: fnRt = {rgs,1'b0,isn[`INSTRUCTION_RB]};
endcase
endfunction
2619,6 → 2619,7
`CAS: IsRFW = TRUE;
`AMO: IsRFW = TRUE;
`CSRRW: IsRFW = TRUE;
`AUIPC: IsRFW = TRUE;
`LUI: IsRFW = TRUE;
default: IsRFW = FALSE;
endcase
3029,7 → 3030,7
.ack_o(dc_ack),
.we_i(we_o),
.adr_i(adr_o[15:0]),
.dat_i(dat_o[31:0]),
.dat_i(dat_o[47:0]),
.cmpgrp(cr0[10:8]),
.freezePC(freezePC),
.regLR(regLR),
5431,7 → 5432,7
iqentry_rmw[n] <= FALSE;
iqentry_pc[n] <= RSTPC;
iqentry_instr[n] <= `NOP_INSN;
iqentry_insln[n] <= 4'd4;
iqentry_insln[n] <= 3'd4;
iqentry_preload[n] <= FALSE;
iqentry_mem[n] <= FALSE;
iqentry_memndx[n] <= FALSE;
5718,55 → 5719,44
 
2'b01:
if (canq1) begin
if (IsVector(fetchbuf1_instr) && SUP_VECTOR) begin
vqe1 <= vqe1 + 4'd1;
if (IsVCmprss(fetchbuf1_instr)) begin
if (vm[fetchbuf1_instr[25:23]][vqe1])
vqet1 <= vqet1 + 4'd1;
end
else
vqet1 <= vqet1 + 4'd1;
if (vqe1 >= vl-2)
nop_fetchbuf <= fetchbuf ? 4'b0100 : 4'b0001;
enque1(tail0, fetchbuf1_thrd ? seq_num1 : seq_num, vqe1);
if (fetchbuf1_thrd)
seq_num1 <= seq_num1 + 5'd1;
else
seq_num <= seq_num + 5'd1;
if (fetchbuf1_rfw) begin
rf_source[ Rt1s ] <= { 1'b0, fetchbuf1_memld, tail0 }; // top bit indicates ALU/MEM bus
rf_v [Rt1s] <= `INV;
end
if (canq2 && vqe1 < vl-2) begin
vqe1 <= vqe1 + 4'd2;
if (IsVCmprss(fetchbuf1_instr)) begin
if (vm[fetchbuf1_instr[25:23]][vqe1+6'd1])
vqet1 <= vqet1 + 4'd2;
end
else
vqet1 <= vqet1 + 4'd2;
enque1(tail1, fetchbuf1_thrd ? seq_num1 + 5'd1 : seq_num + 5'd1, vqe1 + 6'd1);
if (fetchbuf1_thrd)
seq_num1 <= seq_num1 + 5'd2;
else
seq_num <= seq_num + 5'd2;
if (fetchbuf1_rfw) begin
rf_source[ Rt1s ] <= { 1'b0, fetchbuf1_memld, tail1 }; // top bit indicates ALU/MEM bus
rf_v [Rt1s] <= `INV;
end
end
end
else begin
enque1(tail0, fetchbuf1_thrd ? seq_num1 : seq_num, 6'd0);
if (fetchbuf1_thrd)
seq_num1 <= seq_num1 + 5'd1;
else
seq_num <= seq_num + 5'd1;
if (fetchbuf1_rfw) begin
rf_source[ Rt1s ] <= { 1'b0, fetchbuf1_memld, tail0 }; // top bit indicates ALU/MEM bus
rf_v [Rt1s] <= `INV;
end
end
if (fetchbuf1_thrd)
seq_num1 <= seq_num1 + 5'd1;
else
seq_num <= seq_num + 5'd1;
if (fetchbuf1_rfw) begin
rf_source[ Rt1s ] <= { 1'b0, fetchbuf1_memld, tail0 }; // top bit indicates ALU/MEM bus
rf_v [Rt1s] <= `INV;
end
if (IsVector(fetchbuf1_instr) && SUP_VECTOR) begin
vqe1 <= vqe1 + 4'd1;
if (IsVCmprss(fetchbuf1_instr)) begin
if (vm[fetchbuf1_instr[25:23]][vqe1])
vqet1 <= vqet1 + 4'd1;
end
else
vqet1 <= vqet1 + 4'd1;
if (vqe1 >= vl-2)
nop_fetchbuf <= fetchbuf ? 4'b0100 : 4'b0001;
enque1(tail0, fetchbuf1_thrd ? seq_num1 : seq_num, vqe1);
if (canq2 && vqe1 < vl-2) begin
vqe1 <= vqe1 + 4'd2;
if (IsVCmprss(fetchbuf1_instr)) begin
if (vm[fetchbuf1_instr[25:23]][vqe1+6'd1])
vqet1 <= vqet1 + 4'd2;
end
else
vqet1 <= vqet1 + 4'd2;
enque1(tail1, fetchbuf1_thrd ? seq_num1 + 5'd1 : seq_num + 5'd1, vqe1 + 6'd1);
// Override the earlier udpate
if (fetchbuf1_thrd)
seq_num1 <= seq_num1 + 5'd2;
else
seq_num <= seq_num + 5'd2;
end
end
else begin
enque1(tail0, fetchbuf1_thrd ? seq_num1 : seq_num, 6'd0);
end
end
 
2'b10:
7923,7 → 7913,7
end
$display("FCU");
$display("%d %h %h %h %h #", fcu_v, fcu_bus, fcu_argI, fcu_argA, fcu_argB);
$display("%c %h %h #", fcu_branchmiss?"m":" ", fcu_sourceid, fcu_misspc);
$display("%c %h %h %h %h #", fcu_branchmiss?"m":" ", fcu_sourceid, fcu_misspc, fcu_nextpc, fcu_brdisp);
$display("Commit");
$display("0: %c %h %o %d #", commit0_v?"v":" ", commit0_bus, commit0_id, commit0_tgt[4:0]);
$display("1: %c %h %o %d #", commit1_v?"v":" ", commit1_bus, commit1_id, commit1_tgt[4:0]);
8267,6 → 8257,10
iqentry_a0 [nn] <= bus[`IB_CONST];
iqentry_imm [nn] <= bus[`IB_IMM];
// iqentry_insln[nn] <= bus[`IB_LN];
if (iqentry_insln[nn] != bus[`IB_LN]) begin
$display("Insn length mismatch.");
$stop;
end
iqentry_jal [nn] <= bus[`IB_JAL];
iqentry_ret [nn] <= bus[`IB_RET];
iqentry_irq [nn] <= bus[`IB_IRQ];
8299,6 → 8293,22
iqentry_fsync[nn] <= bus[`IB_FSYNC];
iqentry_rfw [nn] <= bus[`IB_RFW];
iqentry_we [nn] <= bus[`IB_WE];
/*
if (iqentry_vector[nn]) begin
iqentry_tgt[nn][RBIT:6] <= iqentry_Ra[nn][RBIT:6];
if (iqentry_Ra[nn][RBIT:6]==6'd0)
iqentry_tgt[nn][RBIT:6] = 6'd0;
else begin
if (iqentry_vcmprss[nn]) begin
if (vm[iqentry_instr[nn][25:23]][iqentry_Ra[nn][RBIT:6]])
if (qcnt==2'd2 && iqentry_vector[(nn-1)%QENTRIES] && iqentry_Ra[(nn-1)%QENTRIES][RBIT:6] >= 6'd1)
iqentry_tgt[nn][RBIT:6] <= iqentry_tgt[(nn-2)%QENTRIES][RBIT:6] + 6'd2;
else
iqentry_tgt[nn][RBIT:6] <= iqentry_tgt[(nn-1)%QENTRIES][RBIT:6] + 6'd1;
end
end
end
*/
end
end
endtask
/FT64v5/rtl/twoway/FT64_fetchbuf.v
72,7 → 72,7
output ack_o;
input we_i;
input [15:0] adr_i;
input [31:0] dat_i;
input [47:0] dat_i;
input [2:0] cmpgrp;
input freezePC;
input thread_en;
114,8 → 114,8
output [47:0] fetchbuf1_instr;
output [AMSB:0] fetchbuf0_pc;
output [AMSB:0] fetchbuf1_pc;
output reg [3:0] fetchbuf0_insln;
output reg [3:0] fetchbuf1_insln;
output [2:0] fetchbuf0_insln;
output [2:0] fetchbuf1_insln;
output fetchbuf0_v;
output fetchbuf1_v;
input [47:0] codebuf0;
164,18 → 164,26
IsRTI = isn[`INSTRUCTION_OP]==`R2 && isn[`INSTRUCTION_S2]==`RTI;
endfunction
 
function [3:0] fnInsLength;
function [2:0] fnInsLength;
input [47:0] ins;
if (ins[`INSTRUCTION_OP]==`CMPRSSD)
fnInsLength = 4'd2;
fnInsLength = 3'd2;
else
case(ins[7:6])
2'd0: fnInsLength = 4'd4;
2'd1: fnInsLength = 4'd6;
default: fnInsLength = 4'd2;
2'd0: fnInsLength = 3'd4;
2'd1: fnInsLength = 3'd6;
default: fnInsLength = 3'd2;
endcase
endfunction
 
wire [2:0] fetchbufA_inslen;
wire [2:0] fetchbufB_inslen;
wire [2:0] fetchbufC_inslen;
wire [2:0] fetchbufD_inslen;
FT64_InsLength uilA (fetchbufA_instr, fetchbufA_inslen);
FT64_InsLength uilB (fetchbufB_instr, fetchbufB_inslen);
FT64_InsLength uilC (fetchbufC_instr, fetchbufC_inslen);
FT64_InsLength uilD (fetchbufD_instr, fetchbufD_inslen);
 
wire [47:0] xinsn0;
wire [47:0] xinsn1;
199,7 → 207,7
reg [47:0] DecompressTable [0:2047];
always @(posedge clk)
if (cs_i & cyc_i & stb_i & we_i)
DecompressTable[adr_i[12:3]] <= dat_i;
DecompressTable[adr_i[12:3]] <= dat_i[47:0];
wire [47:0] expand0 = DecompressTable[{cmpgrp,insn0[15:8]}];
wire [47:0] expand1 = DecompressTable[{cmpgrp,insn1[15:8]}];
 
228,7 → 236,7
`JMP,`CALL: branch_pcA = fetchbufA_instr[6] ? {fetchbufA_instr[39:8],1'b0} : {fetchbufA_pc[31:25],fetchbufA_instr[31:8],1'b0};
`R2: branch_pcA = btgtA; // RTI
`BRK,`JAL: branch_pcA = btgtA;
default: branch_pcA = fetchbufA_pc + {{20{fetchbufA_instr[31]}},fetchbufA_instr[31:21],1'b0} + fnInsLength(fetchbufA_instr);
default: branch_pcA = fetchbufA_pc + {{20{fetchbufA_instr[31]}},fetchbufA_instr[31:21],1'b0} + fetchbufA_inslen;
endcase
 
always @*
237,7 → 245,7
`JMP,`CALL: branch_pcB = fetchbufB_instr[6] ? {fetchbufB_instr[39:8],1'b0} : {fetchbufB_pc[31:25],fetchbufB_instr[31:8],1'b0};
`R2: branch_pcB = btgtB; // RTI
`BRK,`JAL: branch_pcB = btgtB;
default: branch_pcB = fetchbufB_pc + {{20{fetchbufB_instr[31]}},fetchbufB_instr[31:21],1'b0} + fnInsLength(fetchbufB_instr);
default: branch_pcB = fetchbufB_pc + {{20{fetchbufB_instr[31]}},fetchbufB_instr[31:21],1'b0} + fetchbufB_inslen;
endcase
 
always @*
246,7 → 254,7
`JMP,`CALL: branch_pcC = fetchbufC_instr[6] ? {fetchbufC_instr[39:8],1'b0} : {fetchbufC_pc[31:25],fetchbufC_instr[31:8],1'b0};
`R2: branch_pcC = btgtC; // RTI
`BRK,`JAL: branch_pcC = btgtC;
default: branch_pcC = fetchbufC_pc + {{20{fetchbufC_instr[31]}},fetchbufC_instr[31:21],1'b0} + fnInsLength(fetchbufC_instr);
default: branch_pcC = fetchbufC_pc + {{20{fetchbufC_instr[31]}},fetchbufC_instr[31:21],1'b0} + fetchbufC_inslen;
endcase
 
always @*
255,7 → 263,7
`JMP,`CALL: branch_pcD = fetchbufD_instr[6] ? {fetchbufD_instr[39:8],1'b0} : {fetchbufD_pc[31:25],fetchbufD_instr[31:8],1'b0};
`R2: branch_pcD = btgtD; // RTI
`BRK,`JAL: branch_pcD = btgtD;
default: branch_pcD = fetchbufD_pc + {{20{fetchbufD_instr[31]}},fetchbufD_instr[31:21],1'b0} + fnInsLength(fetchbufD_instr);
default: branch_pcD = fetchbufD_pc + {{20{fetchbufD_instr[31]}},fetchbufD_instr[31:21],1'b0} + fetchbufD_inslen;
endcase
 
wire take_branchA = ({fetchbufA_v, IsBranch(fetchbufA_instr), predict_takenA} == {`VAL, `TRUE, `TRUE}) ||
793,32 → 801,35
end
 
assign fetchbuf0_instr = (fetchbuf == 1'b0) ? fetchbufA_instr : fetchbufC_instr;
assign fetchbuf0_insln = (fetchbuf == 1'b0) ? fetchbufA_inslen: fetchbufC_inslen;
assign fetchbuf0_v = (fetchbuf == 1'b0) ? fetchbufA_v : fetchbufC_v ;
assign fetchbuf0_pc = (fetchbuf == 1'b0) ? fetchbufA_pc : fetchbufC_pc ;
assign fetchbuf1_instr = (fetchbuf == 1'b0) ? fetchbufB_instr : fetchbufD_instr;
assign fetchbuf1_insln = (fetchbuf == 1'b0) ? fetchbufB_inslen: fetchbufD_inslen;
assign fetchbuf1_v = (fetchbuf == 1'b0) ? fetchbufB_v : fetchbufD_v ;
assign fetchbuf1_pc = (fetchbuf == 1'b0) ? fetchbufB_pc : fetchbufD_pc ;
assign fetchbuf0_thrd = 1'b0;
assign fetchbuf1_thrd = thread_en;
 
reg [2:0] insln0, insln1;
always @*
begin
if (insn0[5:0]==`CMPRSSD)
fetchbuf0_insln <= 4'd2;
insln0 <= 3'd2;
else if (insn0[7:6]==2'b00 && insn0[`INSTRUCTION_OP]==`EXEC)
fetchbuf0_insln <= fnInsLength(codebuf0);
insln0 <= fnInsLength(codebuf0);
else
fetchbuf0_insln <= fnInsLength(insn0);
insln0 <= fnInsLength(insn0);
end
 
always @*
begin
if (insn1[5:0]==`CMPRSSD)
fetchbuf1_insln <= 4'd2;
insln1 <= 3'd2;
else if (insn1[7:6]==2'b00 && insn1[`INSTRUCTION_OP]==`EXEC)
fetchbuf1_insln <= fnInsLength(codebuf1);
insln1 <= fnInsLength(codebuf1);
else
fetchbuf1_insln <= fnInsLength(insn1);
insln1 <= fnInsLength(insn1);
end
 
reg [47:0] cinsn0, cinsn1;
854,11 → 865,11
fetchbufA_pc <= pc0;
if (phit && ~freezePC) begin
if (thread_en)
pc0 <= pc0 + fetchbuf0_insln;
pc0 <= pc0 + insln0;
else if (`WAYS > 1)
pc0 <= pc0 + fetchbuf0_insln + fetchbuf1_insln;
pc0 <= pc0 + insln0 + insln1;
else
pc0 <= pc0 + fetchbuf0_insln;
pc0 <= pc0 + insln0;
end
end
endtask
870,9 → 881,9
if (thread_en)
fetchbufB_pc <= pc1;
else
fetchbufB_pc <= pc0 + fetchbuf0_insln;
fetchbufB_pc <= pc0 + insln0;
if (phit & thread_en)
pc1 <= pc1 + fetchbuf1_insln;
pc1 <= pc1 + insln1;
end
endtask
 
891,11 → 902,11
fetchbufC_pc <= pc0;
if (phit && ~freezePC) begin
if (thread_en)
pc0 <= pc0 + fetchbuf0_insln;
pc0 <= pc0 + insln0;
else if (`WAYS > 1)
pc0 <= pc0 + fetchbuf0_insln + fetchbuf1_insln;
pc0 <= pc0 + insln0 + insln1;
else
pc0 <= pc0 + fetchbuf0_insln;
pc0 <= pc0 + insln0;
end
end
endtask
907,9 → 918,9
if (thread_en)
fetchbufD_pc <= pc1;
else
fetchbufD_pc <= pc0 + fetchbuf0_insln;
fetchbufD_pc <= pc0 + insln0;
if (phit & thread_en)
pc1 <= pc1 + fetchbuf1_insln;
pc1 <= pc1 + insln1;
end
endtask
 

powered by: WebSVN 2.1.0

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