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

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v7/] [rtl/] [twoway/] [FT64_fetchbuf_x1.v] - Diff between revs 61 and 66

Only display areas with differences | Details | Blame | View Log

Rev 61 Rev 66
// ============================================================================
// ============================================================================
//        __
//        __
//   \\__/ o\    (C) 2018-2019  Robert Finch, Waterloo
//   \\__/ o\    (C) 2018-2019  Robert Finch, Waterloo
//    \  __ /    All rights reserved.
//    \  __ /    All rights reserved.
//     \/_//     robfinch<remove>@finitron.ca
//     \/_//     robfinch<remove>@finitron.ca
//       ||
//       ||
//
//
//      FT64_fetchbuf_x1.v
//      FT64_fetchbuf_x1.v
//
//
// This source file is free software: you can redistribute it and/or modify 
// 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 
// 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     
// by the Free Software Foundation, either version 3 of the License, or     
// (at your option) any later version.                                      
// (at your option) any later version.                                      
//                                                                          
//                                                                          
// This source file is distributed in the hope that it will be useful,      
// This source file is distributed in the hope that it will be useful,      
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
// GNU General Public License for more details.                             
// GNU General Public License for more details.                             
//                                                                          
//                                                                          
// You should have received a copy of the GNU General Public License        
// You should have received a copy of the GNU General Public License        
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
//
//
// ============================================================================
// ============================================================================
//
//
`include "FT64_config.vh"
`include "FT64_config.vh"
`include "FT64_defines.vh"
`include "FT64_defines.vh"
 
 
// FETCH
// FETCH
//
//
// fetch exactly one instructions from memory into the fetch buffer
// fetch exactly one instructions from memory into the fetch buffer
// unless either one of the buffers is still full, in which case we
// unless either one of the buffers is still full, in which case we
// do nothing (kinda like alpha approach)
// do nothing (kinda like alpha approach)
//
//
module FT64_fetchbuf_x1(rst, clk4x, clk, fcu_clk,
module FT64_fetchbuf_x1(rst, clk4x, clk, fcu_clk,
        cs_i, cyc_i, stb_i, ack_o, we_i, adr_i, dat_i,
        cs_i, cyc_i, stb_i, ack_o, we_i, adr_i, dat_i,
        cmpgrp,
        cmpgrp,
        freezePC, thread_en, pred_on,
        freezePC, thread_en, pred_on,
        regLR,
        regLR,
  insn0, phit,
  insn0, phit,
  threadx,
  threadx,
  branchmiss, misspc, branchmiss_thrd, predict_taken0,
  branchmiss, misspc, branchmiss_thrd, predict_taken0,
  predict_takenA, predict_takenB,
  predict_takenA, predict_takenB,
  queued1, queuedNop,
  queued1, queuedNop,
  pc0, fetchbuf, fetchbufA_v, fetchbufB_v,
  pc0, fetchbuf, fetchbufA_v, fetchbufB_v,
  fetchbufA_instr, fetchbufA_pc, fetchbufA_pbyte,
  fetchbufA_instr, fetchbufA_pc, fetchbufA_pbyte,
  fetchbufB_instr, fetchbufB_pc, fetchbufB_pbyte,
  fetchbufB_instr, fetchbufB_pc, fetchbufB_pbyte,
  fetchbuf0_instr, fetchbuf0_insln,
  fetchbuf0_instr, fetchbuf0_insln,
  fetchbuf0_thrd,
  fetchbuf0_thrd,
  fetchbuf0_pc,
  fetchbuf0_pc,
  fetchbuf0_v,
  fetchbuf0_v,
  fetchbuf0_pbyte,
  fetchbuf0_pbyte,
  codebuf0,
  codebuf0,
  btgtA, btgtB,
  btgtA, btgtB,
  nop_fetchbuf,
  nop_fetchbuf,
  take_branch0,
  take_branch0,
  stompedRets,
  stompedRets,
  panic
  panic
);
);
parameter AMSB = `AMSB;
parameter AMSB = `AMSB;
parameter RSTPC = 64'hFFFFFFFFFFFC0100;
parameter RSTPC = 64'hFFFFFFFFFFFC0100;
parameter TRUE = 1'b1;
parameter TRUE = 1'b1;
parameter FALSE = 1'b0;
parameter FALSE = 1'b0;
input rst;
input rst;
input clk4x;
input clk4x;
input clk;
input clk;
input fcu_clk;
input fcu_clk;
input cs_i;
input cs_i;
input cyc_i;
input cyc_i;
input stb_i;
input stb_i;
output ack_o;
output ack_o;
input we_i;
input we_i;
input [15:0] adr_i;
input [15:0] adr_i;
input [55:0] dat_i;
input [55:0] dat_i;
input [2:0] cmpgrp;
input [2:0] cmpgrp;
input freezePC;
input freezePC;
input thread_en;
input thread_en;
input pred_on;
input pred_on;
input [4:0] regLR;
input [4:0] regLR;
input [55:0] insn0;
input [55:0] insn0;
input phit;
input phit;
output threadx;
output threadx;
input branchmiss;
input branchmiss;
input [AMSB:0] misspc;
input [AMSB:0] misspc;
input branchmiss_thrd;
input branchmiss_thrd;
output predict_taken0;
output predict_taken0;
input predict_takenA;
input predict_takenA;
input predict_takenB;
input predict_takenB;
input queued1;
input queued1;
input queuedNop;
input queuedNop;
output reg [AMSB:0] pc0;
output reg [AMSB:0] pc0;
output reg fetchbuf;
output reg fetchbuf;
output reg fetchbufA_v;
output reg fetchbufA_v;
output reg fetchbufB_v;
output reg fetchbufB_v;
output fetchbuf0_thrd;
output fetchbuf0_thrd;
output reg [47:0] fetchbufA_instr;
output reg [47:0] fetchbufA_instr;
output reg [7:0] fetchbufA_pbyte;
output reg [7:0] fetchbufA_pbyte;
output reg [47:0] fetchbufB_instr;
output reg [47:0] fetchbufB_instr;
output reg [7:0] fetchbufB_pbyte;
output reg [7:0] fetchbufB_pbyte;
output reg [AMSB:0] fetchbufA_pc;
output reg [AMSB:0] fetchbufA_pc;
output reg [AMSB:0] fetchbufB_pc;
output reg [AMSB:0] fetchbufB_pc;
output [47:0] fetchbuf0_instr;
output [47:0] fetchbuf0_instr;
output [AMSB:0] fetchbuf0_pc;
output [AMSB:0] fetchbuf0_pc;
output [2:0] fetchbuf0_insln;
output [2:0] fetchbuf0_insln;
output fetchbuf0_v;
output fetchbuf0_v;
output [7:0] fetchbuf0_pbyte;
output [7:0] fetchbuf0_pbyte;
input [55:0] codebuf0;
input [55:0] codebuf0;
input [AMSB:0] btgtA;
input [AMSB:0] btgtA;
input [AMSB:0] btgtB;
input [AMSB:0] btgtB;
input [3:0] nop_fetchbuf;
input [3:0] nop_fetchbuf;
output take_branch0;
output take_branch0;
input [3:0] stompedRets;
input [3:0] stompedRets;
output reg [3:0] panic;
output reg [3:0] panic;
integer n;
integer n;
 
 
reg [55:0] cinsn0;
reg [55:0] cinsn0;
 
 
 
wire iclk = clk;
 
//BUFH ucb1 (.I(clk), .O(iclk));
 
 
//`include "FT64_decode.vh"
//`include "FT64_decode.vh"
 
 
function IsBranch;
function IsBranch;
input [47:0] isn;
input [47:0] isn;
casex(isn[`INSTRUCTION_OP])
casex(isn[`INSTRUCTION_OP])
`Bcc:   IsBranch = TRUE;
`Bcc:   IsBranch = TRUE;
`BLcc:  IsBranch = TRUE;
`BLcc:  IsBranch = TRUE;
`BBc:   IsBranch = TRUE;
`BBc:   IsBranch = TRUE;
`BEQI:  IsBranch = TRUE;
`BEQI:  IsBranch = TRUE;
`BNEI:  IsBranch = TRUE;
`BNEI:  IsBranch = TRUE;
`BCHK:  IsBranch = TRUE;
`BCHK:  IsBranch = TRUE;
default: IsBranch = FALSE;
default: IsBranch = FALSE;
endcase
endcase
endfunction
endfunction
 
 
function IsJAL;
function IsJAL;
input [47:0] isn;
input [47:0] isn;
IsJAL = isn[`INSTRUCTION_OP]==`JAL;
IsJAL = isn[`INSTRUCTION_OP]==`JAL;
endfunction
endfunction
 
 
function IsJmp;
function IsJmp;
input [47:0] isn;
input [47:0] isn;
IsJmp = isn[`INSTRUCTION_OP]==`JMP && isn[7]==1'b0;
IsJmp = isn[`INSTRUCTION_OP]==`JMP && isn[7]==1'b0;
endfunction
endfunction
 
 
function IsCall;
function IsCall;
input [47:0] isn;
input [47:0] isn;
IsCall = isn[`INSTRUCTION_OP]==`CALL && isn[7]==1'b0;
IsCall = isn[`INSTRUCTION_OP]==`CALL && isn[7]==1'b0;
endfunction
endfunction
 
 
function IsRet;
function IsRet;
input [47:0] isn;
input [47:0] isn;
IsRet = isn[`INSTRUCTION_OP]==`RET;
IsRet = isn[`INSTRUCTION_OP]==`RET;
endfunction
endfunction
 
 
function IsBrk;
function IsBrk;
input [47:0] isn;
input [47:0] isn;
IsBrk = isn[`INSTRUCTION_OP]==`BRK;
IsBrk = isn[`INSTRUCTION_OP]==`BRK;
endfunction
endfunction
 
 
function IsRTI;
function IsRTI;
input [47:0] isn;
input [47:0] isn;
IsRTI = isn[`INSTRUCTION_OP]==`R2 && isn[`INSTRUCTION_S2]==`RTI;
IsRTI = isn[`INSTRUCTION_OP]==`R2 && isn[`INSTRUCTION_S2]==`RTI;
endfunction
endfunction
 
 
function IsExec;
function IsExec;
input [47:0] isn;
input [47:0] isn;
if (isn[7:6]==2'b00)
if (isn[7:6]==2'b00)
        case(isn[`INSTRUCTION_OP])
        case(isn[`INSTRUCTION_OP])
        `R2:
        `R2:
                case(isn[`INSTRUCTION_S2])
                case(isn[`INSTRUCTION_S2])
                `R1:
                `R1:
                        case(isn[22:18])
                        case(isn[22:18])
                        `EXEC:  IsExec = TRUE;
                        `EXEC:  IsExec = TRUE;
                        default:        IsExec = FALSE;
                        default:        IsExec = FALSE;
                        endcase
                        endcase
                default:        IsExec = FALSE;
                default:        IsExec = FALSE;
                endcase
                endcase
        default:        IsExec = FALSE;
        default:        IsExec = FALSE;
        endcase
        endcase
else
else
        IsExec = FALSE;
        IsExec = FALSE;
endfunction
endfunction
 
 
function [2:0] fnInsLength;
function [2:0] fnInsLength;
input [47:0] ins;
input [47:0] ins;
`ifdef SUPPORT_DCI
`ifdef SUPPORT_DCI
if (ins[`INSTRUCTION_OP]==`CMPRSSD)
if (ins[`INSTRUCTION_OP]==`CMPRSSD)
        fnInsLength = 3'd2 | pred_on;
        fnInsLength = 3'd2 | pred_on;
else
else
`endif
`endif
        case(ins[7:6])
        case(ins[7:6])
        2'd0:   fnInsLength = 3'd4 | pred_on;
        2'd0:   fnInsLength = 3'd4 | pred_on;
        2'd1:   fnInsLength = 3'd6 | pred_on;
        2'd1:   fnInsLength = 3'd6 | pred_on;
        default:        fnInsLength = 3'd2 | pred_on;
        default:        fnInsLength = 3'd2 | pred_on;
        endcase
        endcase
endfunction
endfunction
 
 
wire [2:0] fetchbufA_inslen;
wire [2:0] fetchbufA_inslen;
wire [2:0] fetchbufB_inslen;
wire [2:0] fetchbufB_inslen;
FT64_InsLength uilA (fetchbufA_instr, fetchbufA_inslen, pred_on);
FT64_InsLength uilA (fetchbufA_instr, fetchbufA_inslen, pred_on);
FT64_InsLength uilB (fetchbufB_instr, fetchbufB_inslen, pred_on);
FT64_InsLength uilB (fetchbufB_instr, fetchbufB_inslen, pred_on);
 
 
wire [47:0] xinsn0;
wire [47:0] xinsn0;
 
 
FT64_iexpander ux1
FT64_iexpander ux1
(
(
        .cinstr(pred_on ? insn0[23:8] : insn0[15:0]),
        .cinstr(pred_on ? insn0[23:8] : insn0[15:0]),
        .expand(xinsn0)
        .expand(xinsn0)
);
);
 
 
 
 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
// Table of decompressed instructions.
// Table of decompressed instructions.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
assign ack_o = cs_i & cyc_i & stb_i;
assign ack_o = cs_i & cyc_i & stb_i;
`ifdef SUPPORT_DCI
`ifdef SUPPORT_DCI
reg [47:0] DecompressTable [0:2047];
reg [47:0] DecompressTable [0:2047];
always @(posedge clk)
always @(posedge clk)
        if (cs_i & cyc_i & stb_i & we_i)
        if (cs_i & cyc_i & stb_i & we_i)
                DecompressTable[adr_i[12:3]] <= dat_i[47:0];
                DecompressTable[adr_i[12:3]] <= dat_i[47:0];
wire [47:0] expand0 = DecompressTable[{cmpgrp,pred_on ? insn0[23:16]:insn0[15:8]}];
wire [47:0] expand0 = DecompressTable[{cmpgrp,pred_on ? insn0[23:16]:insn0[15:8]}];
`endif
`endif
 
 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
 
 
reg thread;
reg thread;
reg stompedRet;
reg stompedRet;
reg ret0Counted;
reg ret0Counted;
wire [AMSB:0] retpc0;
wire [AMSB:0] retpc0;
 
 
assign predict_taken0 = (fetchbuf==1'b0) ? ({fetchbufA_v, IsBranch(fetchbufA_instr), predict_takenA}  == {`VAL, `TRUE, `TRUE})
assign predict_taken0 = (fetchbuf==1'b0) ? ({fetchbufA_v, IsBranch(fetchbufA_instr), predict_takenA}  == {`VAL, `TRUE, `TRUE})
                                                                                                                                                                 : ({fetchbufB_v, IsBranch(fetchbufB_instr), predict_takenB}  == {`VAL, `TRUE, `TRUE});
                                                                                                                                                                 : ({fetchbufB_v, IsBranch(fetchbufB_instr), predict_takenB}  == {`VAL, `TRUE, `TRUE});
 
 
reg [AMSB:0] branch_pcA;
reg [AMSB:0] branch_pcA;
reg [AMSB:0] branch_pcB;
reg [AMSB:0] branch_pcB;
 
 
always @*
always @*
begin
begin
case(fetchbufA_instr[`INSTRUCTION_OP])
case(fetchbufA_instr[`INSTRUCTION_OP])
`RET:           branch_pcA = retpc0;
`RET:           branch_pcA = retpc0;
`JMP,`CALL:
`JMP,`CALL:
        begin
        begin
`ifdef JMP40
`ifdef JMP40
        branch_pcA[39:0] = fetchbufA_instr[6] ? {fetchbufA_instr[47:8]} : {fetchbufA_pc[39:24],fetchbufA_instr[31:8]};
        branch_pcA[39:0] = fetchbufA_instr[6] ? {fetchbufA_instr[47:8]} : {fetchbufA_pc[39:24],fetchbufA_instr[31:8]};
`else
`else
        branch_pcA[39:0] = {fetchbufA_pc[39:24],fetchbufA_instr[31:8]};
        branch_pcA[39:0] = {fetchbufA_pc[39:24],fetchbufA_instr[31:8]};
`endif
`endif
        branch_pcA[63:40] = fetchbufA_pc[63:40];
        branch_pcA[63:40] = fetchbufA_pc[63:40];
        end
        end
`R2:            branch_pcA = btgtA;     // RTI
`R2:            branch_pcA = btgtA;     // RTI
`BRK,`JAL:      branch_pcA = btgtA;
`BRK,`JAL:      branch_pcA = btgtA;
default:
default:
        begin
        begin
        branch_pcA[31:0] = fetchbufA_pc[31:0] +
        branch_pcA[31:0] = fetchbufA_pc[31:0] +
                ((fetchbufA_instr[7:6]==2'b01) ? {{4{fetchbufA_instr[47]}},fetchbufA_instr[47:23],fetchbufA_instr[17:16],1'b0} : {{20{fetchbufA_instr[31]}},fetchbufA_instr[31:23],fetchbufA_instr[17:16],1'b0});
                ((fetchbufA_instr[7:6]==2'b01) ? {{4{fetchbufA_instr[47]}},fetchbufA_instr[47:23],fetchbufA_instr[17:16],1'b0} : {{20{fetchbufA_instr[31]}},fetchbufA_instr[31:23],fetchbufA_instr[17:16],1'b0});
        branch_pcA[63:32] = fetchbufA_pc[63:32];
        branch_pcA[63:32] = fetchbufA_pc[63:32];
        end
        end
endcase
endcase
end
end
 
 
always @*
always @*
begin
begin
case(fetchbufB_instr[`INSTRUCTION_OP])
case(fetchbufB_instr[`INSTRUCTION_OP])
`RET:           branch_pcB = retpc0;
`RET:           branch_pcB = retpc0;
`JMP,`CALL:
`JMP,`CALL:
        begin
        begin
`ifdef JMP40
`ifdef JMP40
                branch_pcB[39:0] = fetchbufB_instr[6] ? {fetchbufB_instr[47:8]} : {fetchbufB_pc[39:24],fetchbufB_instr[31:8]};
                branch_pcB[39:0] = fetchbufB_instr[6] ? {fetchbufB_instr[47:8]} : {fetchbufB_pc[39:24],fetchbufB_instr[31:8]};
`else
`else
                branch_pcB[39:0] = {fetchbufB_pc[39:24],fetchbufB_instr[31:8]};
                branch_pcB[39:0] = {fetchbufB_pc[39:24],fetchbufB_instr[31:8]};
`endif
`endif
                branch_pcB[63:40] = fetchbufB_pc[63:40];
                branch_pcB[63:40] = fetchbufB_pc[63:40];
        end
        end
`R2:            branch_pcB = btgtB;     // RTI
`R2:            branch_pcB = btgtB;     // RTI
`BRK,`JAL:      branch_pcB = btgtB;
`BRK,`JAL:      branch_pcB = btgtB;
default:
default:
        begin
        begin
        branch_pcB[31:0] = fetchbufB_pc[31:0] +
        branch_pcB[31:0] = fetchbufB_pc[31:0] +
                ((fetchbufB_instr[7:6]==2'b01) ? {{4{fetchbufB_instr[47]}},fetchbufB_instr[47:23],fetchbufB_instr[17:16],1'b0} : {{20{fetchbufB_instr[31]}},fetchbufB_instr[31:23],fetchbufB_instr[17:16],1'b0});
                ((fetchbufB_instr[7:6]==2'b01) ? {{4{fetchbufB_instr[47]}},fetchbufB_instr[47:23],fetchbufB_instr[17:16],1'b0} : {{20{fetchbufB_instr[31]}},fetchbufB_instr[31:23],fetchbufB_instr[17:16],1'b0});
        branch_pcB[63:32] = fetchbufB_pc[63:32];
        branch_pcB[63:32] = fetchbufB_pc[63:32];
        end
        end
endcase
endcase
end
end
 
 
wire take_branchA = ({fetchbufA_v, IsBranch(fetchbufA_instr), predict_takenA}  == {`VAL, `TRUE, `TRUE}) || ((
wire take_branchA = ({fetchbufA_v, IsBranch(fetchbufA_instr), predict_takenA}  == {`VAL, `TRUE, `TRUE}) || ((
`ifdef FCU_ENH
`ifdef FCU_ENH
                           IsRet(fetchbufA_instr)
                           IsRet(fetchbufA_instr)
                        || IsRTI(fetchbufA_instr)|| IsBrk(fetchbufA_instr) || IsJAL(fetchbufA_instr) ||
                        || IsRTI(fetchbufA_instr)|| IsBrk(fetchbufA_instr) || IsJAL(fetchbufA_instr) ||
`endif
`endif
                           IsJmp(fetchbufA_instr)||IsCall(fetchbufA_instr)) &&
                           IsJmp(fetchbufA_instr)||IsCall(fetchbufA_instr)) &&
                        fetchbufA_v);
                        fetchbufA_v);
wire take_branchB = ({fetchbufB_v, IsBranch(fetchbufB_instr), predict_takenB}  == {`VAL, `TRUE, `TRUE}) || ((
wire take_branchB = ({fetchbufB_v, IsBranch(fetchbufB_instr), predict_takenB}  == {`VAL, `TRUE, `TRUE}) || ((
`ifdef FCU_ENH
`ifdef FCU_ENH
                           IsRet(fetchbufB_instr)
                           IsRet(fetchbufB_instr)
                        || IsRTI(fetchbufB_instr)|| IsBrk(fetchbufB_instr) || IsJAL(fetchbufB_instr) ||
                        || IsRTI(fetchbufB_instr)|| IsBrk(fetchbufB_instr) || IsJAL(fetchbufB_instr) ||
`endif
`endif
                           IsJmp(fetchbufB_instr)||IsCall(fetchbufB_instr)) &&
                           IsJmp(fetchbufB_instr)||IsCall(fetchbufB_instr)) &&
                        fetchbufB_v);
                        fetchbufB_v);
 
 
wire take_branch = (fetchbuf==1'b0) ? take_branchA : take_branchB;
wire take_branch = (fetchbuf==1'b0) ? take_branchA : take_branchB;
assign take_branch0 = take_branch;
assign take_branch0 = take_branch;
 
 
/*
/*
always @*
always @*
begin
begin
        pc0 <= thread_en ? (fetchbuf ? pc0b : pc0a) : pc0a;
        pc0 <= thread_en ? (fetchbuf ? pc0b : pc0a) : pc0a;
        pc1 <= thread_en ? (fetchbuf ? pc1b : pc1a) : pc1a;
        pc1 <= thread_en ? (fetchbuf ? pc1b : pc1a) : pc1a;
end
end
*/
*/
assign threadx = fetchbuf;
assign threadx = fetchbuf;
 
 
`ifdef FCU_ENH
`ifdef FCU_ENH
FT64_RSB #(AMSB) ursb1
FT64_RSB #(AMSB) ursb1
(
(
        .rst(rst),
        .rst(rst),
        .clk(fcu_clk),
        .clk(fcu_clk),
        .regLR(regLR),
        .regLR(regLR),
        .queued1(queued1),
        .queued1(queued1),
        .queued2(1'b0),
        .queued2(1'b0),
        .fetchbuf0_v(fetchbuf0_v),
        .fetchbuf0_v(fetchbuf0_v),
        .fetchbuf0_pc(fetchbuf0_pc),
        .fetchbuf0_pc(fetchbuf0_pc),
        .fetchbuf0_instr(fetchbuf0_instr),
        .fetchbuf0_instr(fetchbuf0_instr),
        .fetchbuf1_v(1'b0),
        .fetchbuf1_v(1'b0),
        .fetchbuf1_pc(RSTPC),
        .fetchbuf1_pc(RSTPC),
        .fetchbuf1_instr(`NOP_INSN),
        .fetchbuf1_instr(`NOP_INSN),
        .stompedRets(stompedRets),
        .stompedRets(stompedRets),
        .stompedRet(stompedRet),
        .stompedRet(stompedRet),
        .pc(retpc0)
        .pc(retpc0)
);
);
 
 
`else
`else
assign retpc0 = RSTPC;
assign retpc0 = RSTPC;
assign retpc1 = RSTPC;
assign retpc1 = RSTPC;
`endif
`endif
 
 
wire peclk, neclk;
wire peclk, neclk;
edge_det ued1 (.rst(rst), .clk(clk4x), .ce(1'b1), .i(clk), .pe(peclk), .ne(neclk), .ee());
edge_det ued1 (.rst(rst), .clk(clk4x), .ce(1'b1), .i(clk), .pe(peclk), .ne(neclk), .ee());
 
 
reg did_branch;
reg did_branch;
 
 
always @(posedge clk)
always @(posedge iclk)
if (rst) begin
if (rst) begin
        pc0 <= RSTPC;
        pc0 <= RSTPC;
        fetchbufA_v <= 1'b0;
        fetchbufA_v <= 1'b0;
        fetchbufB_v <= 1'b0;
        fetchbufB_v <= 1'b0;
        fetchbuf <= 1'b0;
        fetchbuf <= 1'b0;
        panic <= `PANIC_NONE;
        panic <= `PANIC_NONE;
        did_branch <= 1'b0;
        did_branch <= 1'b0;
end
end
else begin
else begin
 
 
        did_branch <= take_branch & ~branchmiss;
        did_branch <= take_branch & ~branchmiss;
 
 
        begin
        begin
 
 
        // On a branch miss with threading enabled all fectch buffers are
        // On a branch miss with threading enabled all fectch buffers are
        // invalidated even though the data in the fetch buffer would be valid
        // invalidated even though the data in the fetch buffer would be valid
        // for the thread that isn't in a branchmiss state. This is done to
        // for the thread that isn't in a branchmiss state. This is done to
        // keep things simple. For the thread that doesn't miss the current
        // keep things simple. For the thread that doesn't miss the current
        // data for the fetch buffer needs to be retrieved again, so the pc
        // data for the fetch buffer needs to be retrieved again, so the pc
        // for that thread is assigned the current fetchbuf pc.
        // for that thread is assigned the current fetchbuf pc.
        // For the thread that misses the pc is simply assigned the misspc.
        // For the thread that misses the pc is simply assigned the misspc.
        if (branchmiss) begin
        if (branchmiss) begin
                pc0 <= misspc;
                pc0 <= misspc;
                fetchbufA_v <= `INV;
                fetchbufA_v <= `INV;
                fetchbufB_v <= `INV;
                fetchbufB_v <= `INV;
                fetchbuf <= 1'b0;
                fetchbuf <= 1'b0;
                $display("********************");
                $display("********************");
                $display("********************");
                $display("********************");
                $display("********************");
                $display("********************");
                $display("Branch miss");
                $display("Branch miss");
                $display("misspc=%h", misspc);
                $display("misspc=%h", misspc);
                $display("********************");
                $display("********************");
                $display("********************");
                $display("********************");
                $display("********************");
                $display("********************");
        end
        end
//      else if (cinsn0[`INSTRUCTION_OP]==`CALL || cinsn0[`INSTRUCTION_OP]==`JMP) begin
//      else if (cinsn0[`INSTRUCTION_OP]==`CALL || cinsn0[`INSTRUCTION_OP]==`JMP) begin
//              pc0[31:0] = cinsn0[6] ? {cinsn0[47:8]} : {pc0[31:24],cinsn0[31:8]};
//              pc0[31:0] = cinsn0[6] ? {cinsn0[47:8]} : {pc0[31:24],cinsn0[31:8]};
//              fetchbufA_v <= `INV;
//              fetchbufA_v <= `INV;
//              fetchbufB_v <= `INV;
//              fetchbufB_v <= `INV;
//              fetchbuf <= 1'b0;
//              fetchbuf <= 1'b0;
//      end
//      end
        else if (take_branch) begin
        else if (take_branch) begin
    if (fetchbuf == 1'b0) begin
    if (fetchbuf == 1'b0) begin
        // In this case fetchbufA must be valid, or take_branch wouldn't be.
        // In this case fetchbufA must be valid, or take_branch wouldn't be.
        case(fetchbufB_v)
        case(fetchbufB_v)
        1'b0:
        1'b0:
                begin
                begin
                                        pc0 <= branch_pcA;
                                        pc0 <= branch_pcA;
                                  fetchbufA_v <= !(queued1|queuedNop);  // if it can be queued, it will
                                  fetchbufA_v <= !(queued1|queuedNop);  // if it can be queued, it will
                                  fetchbuf <= (queued1|queuedNop);
                                  fetchbuf <= (queued1|queuedNop);
                end
                end
        1'b1:
        1'b1:
                        if (did_branch) begin
                        if (did_branch) begin
                                  fetchbufA_v <= !(queued1|queuedNop);  // if it can be queued, it will
                                  fetchbufA_v <= !(queued1|queuedNop);  // if it can be queued, it will
                                  fetchbuf <= (queued1|queuedNop);
                                  fetchbuf <= (queued1|queuedNop);
                                  FetchB();
                                  FetchB();
                        end
                        end
                        else
                        else
                        begin
                        begin
                                        pc0 <= branch_pcA;
                                        pc0 <= branch_pcA;
                                  fetchbufA_v <= !(queued1|queuedNop);  // if it can be queued, it will
                                  fetchbufA_v <= !(queued1|queuedNop);  // if it can be queued, it will
                                        fetchbufB_v <= `INV;
                                        fetchbufB_v <= `INV;
                                  fetchbuf <= (queued1|queuedNop);
                                  fetchbuf <= (queued1|queuedNop);
                        end
                        end
        endcase
        endcase
                end
                end
    else begin
    else begin
        case(fetchbufA_v)
        case(fetchbufA_v)
        1'b0:
        1'b0:
                begin
                begin
                                        pc0 <= branch_pcB;
                                        pc0 <= branch_pcB;
                                  fetchbufB_v <= !(queued1|queuedNop);
                                  fetchbufB_v <= !(queued1|queuedNop);
                                  fetchbuf <= !(queued1|queuedNop);
                                  fetchbuf <= !(queued1|queuedNop);
                                end
                                end
                        1'b1:
                        1'b1:
                                if (did_branch) begin
                                if (did_branch) begin
                                  fetchbufB_v <= !(queued1|queuedNop);
                                  fetchbufB_v <= !(queued1|queuedNop);
                                  fetchbuf <= ~(queued1|queuedNop);
                                  fetchbuf <= ~(queued1|queuedNop);
                                  FetchA();
                                  FetchA();
                                end
                                end
                                else
                                else
                                begin
                                begin
                                        pc0 <= branch_pcB;
                                        pc0 <= branch_pcB;
                                  fetchbufB_v <= !(queued1|queuedNop);
                                  fetchbufB_v <= !(queued1|queuedNop);
                                        fetchbufA_v <= `INV;
                                        fetchbufA_v <= `INV;
                                  fetchbuf <= !(queued1|queuedNop);
                                  fetchbuf <= !(queued1|queuedNop);
                                end
                                end
                        endcase
                        endcase
                end
                end
        end // if branch
        end // if branch
 
 
        else begin      // there is no branchback in the system
        else begin      // there is no branchback in the system
    // update fetchbufX_v and fetchbuf ... relatively simple, as
    // update fetchbufX_v and fetchbuf ... relatively simple, as
    // there are no backwards branches in the mix
    // there are no backwards branches in the mix
          if (fetchbuf == 1'b0) case ({fetchbufA_v, (queued1|queuedNop)})
          if (fetchbuf == 1'b0) case ({fetchbufA_v, (queued1|queuedNop)})
                2'b00: ;        // do nothing
                2'b00: ;        // do nothing
                2'b10: ;
                2'b10: ;
                2'b11: begin fetchbufA_v <= `INV; fetchbuf <= ~fetchbuf; end
                2'b11: begin fetchbufA_v <= `INV; fetchbuf <= ~fetchbuf; end
                default:  panic <= `PANIC_INVALIDIQSTATE;
                default:  panic <= `PANIC_INVALIDIQSTATE;
                endcase
                endcase
          else case ({fetchbufB_v, (queued1|queuedNop)})
          else case ({fetchbufB_v, (queued1|queuedNop)})
                2'b00: ;        // do nothing
                2'b00: ;        // do nothing
                2'b10: ;
                2'b10: ;
                2'b11: begin fetchbufB_v <= `INV; fetchbuf <= ~fetchbuf; end
                2'b11: begin fetchbufB_v <= `INV; fetchbuf <= ~fetchbuf; end
                default:  panic <= `PANIC_INVALIDIQSTATE;
                default:  panic <= `PANIC_INVALIDIQSTATE;
                endcase
                endcase
    //
    //
    // get data iff the fetch buffers are empty
    // get data iff the fetch buffers are empty
    //
    //
    if (fetchbufA_v == `INV) begin
    if (fetchbufA_v == `INV) begin
        FetchA();
        FetchA();
        // fetchbuf steering logic correction
        // fetchbuf steering logic correction
        if (fetchbufB_v==`INV && phit)
        if (fetchbufB_v==`INV && phit)
          fetchbuf <= 1'b0;
          fetchbuf <= 1'b0;
    end
    end
    else if (fetchbufB_v == `INV) begin
    else if (fetchbufB_v == `INV) begin
            FetchB();
            FetchB();
          end
          end
        end
        end
  //
  //
  // get data iff the fetch buffers are empty
  // get data iff the fetch buffers are empty
  //
  //
  if (fetchbufA_v == `INV && fetchbufB_v == `INV) begin
  if (fetchbufA_v == `INV && fetchbufB_v == `INV) begin
        FetchA();
        FetchA();
    fetchbuf <= 1'b0;
    fetchbuf <= 1'b0;
  end
  end
//  // Steer fetchbuf to the valid buffer.
//  // Steer fetchbuf to the valid buffer.
//  else if (fetchbufB_v == `INV)
//  else if (fetchbufB_v == `INV)
//      fetchbuf <= 1'b0;
//      fetchbuf <= 1'b0;
//  else if (fetchbufA_v == `INV)
//  else if (fetchbufA_v == `INV)
//              fetchbuf <= 1'b1;
//              fetchbuf <= 1'b1;
//  else if (fetchbufA_v == `INV) begin
//  else if (fetchbufA_v == `INV) begin
//      FetchA();
//      FetchA();
//      end
//      end
//      else if (fetchbufB_v == `INV) begin
//      else if (fetchbufB_v == `INV) begin
//              FetchB();
//              FetchB();
//      end
//      end
end
end
 
 
        // The fetchbuffer is invalidated at the end of a vector instruction
        // The fetchbuffer is invalidated at the end of a vector instruction
        // queue.
        // queue.
        if (nop_fetchbuf[0])  fetchbufA_v <= `INV;
        if (nop_fetchbuf[0])  fetchbufA_v <= `INV;
        if (nop_fetchbuf[1])  fetchbufB_v <= `INV;
        if (nop_fetchbuf[1])  fetchbufB_v <= `INV;
end
end
 
 
assign fetchbuf0_instr = (fetchbuf == 1'b0) ? fetchbufA_instr : fetchbufB_instr;
assign fetchbuf0_instr = (fetchbuf == 1'b0) ? fetchbufA_instr : fetchbufB_instr;
assign fetchbuf0_insln = (fetchbuf == 1'b0) ? fetchbufA_inslen: fetchbufB_inslen;
assign fetchbuf0_insln = (fetchbuf == 1'b0) ? fetchbufA_inslen: fetchbufB_inslen;
assign fetchbuf0_v     = (fetchbuf == 1'b0) ? fetchbufA_v     : fetchbufB_v    ;
assign fetchbuf0_v     = (fetchbuf == 1'b0) ? fetchbufA_v     : fetchbufB_v    ;
assign fetchbuf0_pc    = (fetchbuf == 1'b0) ? fetchbufA_pc    : fetchbufB_pc   ;
assign fetchbuf0_pc    = (fetchbuf == 1'b0) ? fetchbufA_pc    : fetchbufB_pc   ;
assign fetchbuf0_thrd  = 1'b0;
assign fetchbuf0_thrd  = 1'b0;
assign fetchbuf0_pbyte = (fetchbuf == 1'b0) ? fetchbufA_pbyte : fetchbufB_pbyte;
assign fetchbuf0_pbyte = (fetchbuf == 1'b0) ? fetchbufA_pbyte : fetchbufB_pbyte;
 
 
reg [2:0] insln0;
reg [2:0] insln0;
always @*
always @*
begin
begin
`ifdef SUPPORT_DCI
`ifdef SUPPORT_DCI
        if (insn0[5:0]==`CMPRSSD)
        if (insn0[5:0]==`CMPRSSD)
                insln0 <= 3'd2 | pred_on;
                insln0 <= 3'd2 | pred_on;
        else
        else
`endif
`endif
        if (IsExec(insn0))
        if (IsExec(insn0))
                insln0 <= fnInsLength(codebuf0);        //???? should be 4?
                insln0 <= fnInsLength(codebuf0);        //???? should be 4?
        else
        else
                insln0 <= fnInsLength(insn0);
                insln0 <= fnInsLength(insn0);
end
end
 
 
 
 
always @*
always @*
begin
begin
`ifdef SUPPORT_DCI
`ifdef SUPPORT_DCI
        if (insn0[13:8]==`CMPRSSD && pred_on)
        if (insn0[13:8]==`CMPRSSD && pred_on)
                cinsn0 <= expand0;
                cinsn0 <= expand0;
        else if (insn0[5:0]==`CMPRSSD && !pred_on)
        else if (insn0[5:0]==`CMPRSSD && !pred_on)
                cinsn0 <= expand0;
                cinsn0 <= expand0;
        else
        else
`endif
`endif
        if (IsExec(insn0) && !pred_on)
        if (IsExec(insn0) && !pred_on)
                cinsn0 <= codebuf0;
                cinsn0 <= codebuf0;
        else if (IsExec(insn0[55:8]) && pred_on)
        else if (IsExec(insn0[55:8]) && pred_on)
                cinsn0 <= codebuf0;
                cinsn0 <= codebuf0;
        else if (insn0[15] & pred_on)
        else if (insn0[15] & pred_on)
                cinsn0 <= {xinsn0,insn0[7:0]};
                cinsn0 <= {xinsn0,insn0[7:0]};
        else if (insn0[7] & ~pred_on)
        else if (insn0[7] & ~pred_on)
                cinsn0 <= xinsn0;
                cinsn0 <= xinsn0;
        else
        else
                cinsn0 <= insn0;
                cinsn0 <= insn0;
end
end
 
 
task FetchA;
task FetchA;
begin
begin
        fetchbufA_instr <= pred_on ? cinsn0[55:8] : cinsn0[47:0];
        fetchbufA_instr <= pred_on ? cinsn0[55:8] : cinsn0[47:0];
        fetchbufA_pbyte = cinsn0[7:0];
        fetchbufA_pbyte = cinsn0[7:0];
        fetchbufA_v <= `VAL;
        fetchbufA_v <= `VAL;
        fetchbufA_pc <= pc0;
        fetchbufA_pc <= pc0;
        if (phit && ~freezePC)
        if (phit && ~freezePC)
                pc0 <= pc0 + insln0;
                pc0[31:0] <= pc0[31:0] + insln0;
        else
//      else
                pc0 <= pc0;
//              pc0 <= pc0;
end
end
endtask
endtask
 
 
task FetchB;
task FetchB;
begin
begin
        fetchbufB_instr <= pred_on ? cinsn0[55:8] : cinsn0[47:0];
        fetchbufB_instr <= pred_on ? cinsn0[55:8] : cinsn0[47:0];
        fetchbufB_pbyte = cinsn0[7:0];
        fetchbufB_pbyte = cinsn0[7:0];
        fetchbufB_v <= `VAL;
        fetchbufB_v <= `VAL;
        fetchbufB_pc <= pc0;
        fetchbufB_pc <= pc0;
        if (phit && ~freezePC)
        if (phit && ~freezePC)
                pc0 <= pc0 + insln0;
                pc0[31:0] <= pc0[31:0] + insln0;
        else
//      else
                pc0 <= pc0;
//              pc0 <= pc0;
end
end
endtask
endtask
 
 
endmodule
endmodule
 
 

powered by: WebSVN 2.1.0

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