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