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

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v5/] [rtl/] [common/] [FT64_RSB.v] - Diff between revs 48 and 49

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 48 Rev 49
// ============================================================================
// ============================================================================
//        __
//        __
//   \\__/ o\    (C) 2018  Robert Finch, Waterloo
//   \\__/ o\    (C) 2018  Robert Finch, Waterloo
//    \  __ /    All rights reserved.
//    \  __ /    All rights reserved.
//     \/_//     robfinch<remove>@finitron.ca
//     \/_//     robfinch<remove>@finitron.ca
//       ||
//       ||
//
//
//      FT64_RSB.v
//      FT64_RSB.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_defines.vh"
`include "FT64_defines.vh"
 
 
// Return address stack predictor is updated during the fetch stage on the 
// Return address stack predictor is updated during the fetch stage on the 
// assumption that previous flow controls (branches) predicted correctly.
// assumption that previous flow controls (branches) predicted correctly.
// Otherwise many small routines wouldn't predict the return address
// Otherwise many small routines wouldn't predict the return address
// correctly because they hit the RET before the CALL reaches the 
// correctly because they hit the RET before the CALL reaches the 
// commit stage.
// commit stage.
 
 
module FT64_RSB(rst, clk, regLR, queued1, queued2,
module FT64_RSB(rst, clk, regLR, queued1, queued2,
        fetchbuf0_v, fetchbuf0_pc, fetchbuf0_instr,
        fetchbuf0_v, fetchbuf0_pc, fetchbuf0_instr,
        fetchbuf1_v, fetchbuf1_pc, fetchbuf1_instr,
        fetchbuf1_v, fetchbuf1_pc, fetchbuf1_instr,
        stompedRets, stompedRet,
        stompedRets, stompedRet,
        pc
        pc
);
);
parameter AMSB = 31;
parameter AMSB = 31;
parameter DEPTH = 16;
parameter DEPTH = 16;
input rst;
input rst;
input clk;
input clk;
input [4:0] regLR;
input [4:0] regLR;
input queued1;
input queued1;
input queued2;
input queued2;
input fetchbuf0_v;
input fetchbuf0_v;
input [47:0] fetchbuf0_instr;
input [47:0] fetchbuf0_instr;
input [AMSB:0] fetchbuf0_pc;
input [AMSB:0] fetchbuf0_pc;
input fetchbuf1_v;
input fetchbuf1_v;
input [47:0] fetchbuf1_instr;
input [47:0] fetchbuf1_instr;
input [AMSB:0] fetchbuf1_pc;
input [AMSB:0] fetchbuf1_pc;
input [3:0] stompedRets;
input [3:0] stompedRets;
input stompedRet;
input stompedRet;
output [AMSB:0] pc;
output [AMSB:0] pc;
 
 
parameter RSTPC = 32'hFFFC0100;
parameter RSTPC = 32'hFFFC0100;
integer n;
integer n;
reg [AMSB:0] ras [0:DEPTH-1];
reg [AMSB:0] ras [0:DEPTH-1];
reg [4:0] rasp;
reg [3:0] rasp;
assign pc = ras[rasp];
assign pc = ras[rasp];
 
reg [47:0] lasti0, lasti1;
 
 
always @(posedge clk)
always @(posedge clk)
if (rst) begin
if (rst) begin
    for (n = 0; n < 32; n = n + 1)
        lasti0 <= `NOP_INSN;
 
        lasti1 <= `NOP_INSN;
 
  for (n = 0; n < DEPTH; n = n + 1)
         ras[n] <= RSTPC;
         ras[n] <= RSTPC;
     rasp <= 5'd0;
  rasp <= 4'd0;
end
end
else begin
else begin
        if (fetchbuf0_v && fetchbuf1_v && (queued1 || queued2)) begin
        if (fetchbuf0_v && fetchbuf1_v && (queued1 || queued2)) begin
 
                // Make sure the instruction changed between clock cycles.
 
                lasti0 <= fetchbuf0_instr;
 
                lasti1 <= fetchbuf1_instr;
 
                if (fetchbuf0_instr != lasti0 || fetchbuf1_instr != lasti1) begin
        case(fetchbuf0_instr[`INSTRUCTION_OP])
        case(fetchbuf0_instr[`INSTRUCTION_OP])
        `JAL:
        `JAL:
                begin
                begin
                        // JAL LR,xxxx  assume call
                        // JAL LR,xxxx  assume call
                        if (fetchbuf0_instr[`INSTRUCTION_RB]==regLR) begin
                        if (fetchbuf0_instr[`INSTRUCTION_RB]==regLR) begin
                        ras[((rasp-6'd1)&(DEPTH-1))] <= fetchbuf0_pc + 32'd4;
                        ras[((rasp-6'd1)&(DEPTH-1))] <= fetchbuf0_pc + (fetchbuf0_instr[6] ? 32'd6 : 32'd4);
                        rasp <= rasp - 4'd1;
                        rasp <= rasp - 4'd1;
                        end
                        end
                        // JAL r0,[r29] assume a ret
                        // JAL r0,[r29] assume a ret
                        else if (fetchbuf0_instr[`INSTRUCTION_RB]==5'd00 &&
                        else if (fetchbuf0_instr[`INSTRUCTION_RB]==5'd00 &&
                                         fetchbuf0_instr[`INSTRUCTION_RA]==regLR) begin
                                         fetchbuf0_instr[`INSTRUCTION_RA]==regLR) begin
                                rasp <= rasp + 4'd1;
                                rasp <= rasp + 4'd1;
                        end
                        end
                end
                end
        `CALL:
        `CALL:
            begin
            begin
                 ras[((rasp-6'd1)&(DEPTH-1))] <= fetchbuf0_pc + 32'd4;
                 ras[((rasp-6'd1)&(DEPTH-1))] <= fetchbuf0_pc + (fetchbuf0_instr[6] ? 32'd6 : 32'd4);
                 rasp <= rasp - 4'd1;
                 rasp <= rasp - 4'd1;
            end
            end
        `RET:   begin
        `RET:   begin
                        $display("RSP: Added 1");
                        $display("RSP: Added 1");
                        rasp <= rasp + 4'd1;
                        rasp <= rasp + 4'd1;
                        end
                        end
        default:        ;
        default:        ;
        endcase
        endcase
        end
        end
 
        end
    else if (fetchbuf1_v && queued1)
    else if (fetchbuf1_v && queued1)
 
        lasti1 <= fetchbuf1_instr;
 
        if (fetchbuf1_instr != lasti1) begin
        case(fetchbuf1_instr[`INSTRUCTION_OP])
        case(fetchbuf1_instr[`INSTRUCTION_OP])
        `JAL:
        `JAL:
                if (fetchbuf1_instr[`INSTRUCTION_RB]==regLR) begin
                if (fetchbuf1_instr[`INSTRUCTION_RB]==regLR) begin
                 ras[((rasp-6'd1)&(DEPTH-1))] <= fetchbuf1_pc + 32'd4;
                 ras[((rasp-6'd1)&(DEPTH-1))] <= fetchbuf1_pc + (fetchbuf1_instr[6] ? 32'd6 : 32'd4);
                 rasp <= rasp - 4'd1;
                 rasp <= rasp - 4'd1;
                end
                end
                else if (fetchbuf1_instr[`INSTRUCTION_RB]==5'd00 &&
                else if (fetchbuf1_instr[`INSTRUCTION_RB]==5'd00 &&
                                 fetchbuf1_instr[`INSTRUCTION_RA]==regLR) begin
                                 fetchbuf1_instr[`INSTRUCTION_RA]==regLR) begin
                        rasp <= rasp + 4'd1;
                        rasp <= rasp + 4'd1;
                end
                end
        `CALL:
        `CALL:
            begin
            begin
                 ras[((rasp-6'd1)&(DEPTH-1))] <= fetchbuf1_pc + 32'd4;
                 ras[((rasp-6'd1)&(DEPTH-1))] <= fetchbuf1_pc + (fetchbuf1_instr[6] ? 32'd6 : 32'd4);
                 rasp <= rasp - 4'd1;
                 rasp <= rasp - 4'd1;
            end
            end
        `RET:   begin
        `RET:   begin
                        rasp <= rasp + 4'd1;
                        rasp <= rasp + 4'd1;
                        $display("RSP: Added 1");
                        $display("RSP: Added 1");
                        end
                        end
        default:        ;
        default:        ;
        endcase
        endcase
 
      end
    else if (fetchbuf0_v && queued1)
    else if (fetchbuf0_v && queued1)
 
        lasti0 <= fetchbuf0_instr;
 
        if (lasti0 != fetchbuf0_instr) begin
        case(fetchbuf0_instr[`INSTRUCTION_OP])
        case(fetchbuf0_instr[`INSTRUCTION_OP])
        `JAL:
        `JAL:
                if (fetchbuf0_instr[`INSTRUCTION_RB]==regLR) begin
                if (fetchbuf0_instr[`INSTRUCTION_RB]==regLR) begin
                 ras[((rasp-6'd1)&(DEPTH-1))] <= fetchbuf0_pc + 32'd4;
                 ras[((rasp-6'd1)&(DEPTH-1))] <= fetchbuf0_pc + (fetchbuf0_instr[6] ? 32'd6 : 32'd4);
                 rasp <= rasp - 4'd1;
                 rasp <= rasp - 4'd1;
                end
                end
                else if (fetchbuf0_instr[`INSTRUCTION_RB]==5'd00 &&
                else if (fetchbuf0_instr[`INSTRUCTION_RB]==5'd00 &&
                                 fetchbuf0_instr[`INSTRUCTION_RA]==regLR) begin
                                 fetchbuf0_instr[`INSTRUCTION_RA]==regLR) begin
                        rasp <= rasp + 4'd1;
                        rasp <= rasp + 4'd1;
                end
                end
        `CALL:
        `CALL:
            begin
            begin
                 ras[((rasp-6'd1)&(DEPTH-1))] <= fetchbuf0_pc + 32'd4;
                 ras[((rasp-6'd1)&(DEPTH-1))] <= fetchbuf0_pc + (fetchbuf0_instr[6] ? 32'd6 : 32'd4);
                 rasp <= rasp - 4'd1;
                 rasp <= rasp - 4'd1;
            end
            end
        `RET:   begin
        `RET:   begin
                        $display("RSP: Added 1");
                        $display("RSP: Added 1");
                        rasp <= rasp + 4'd1;
                        rasp <= rasp + 4'd1;
                        end
                        end
        default:        ;
        default:        ;
        endcase
        endcase
 
      end
/*
/*
    if (stompedRets > 4'd0) begin
    if (stompedRets > 4'd0) begin
        $display("Stomped Rets: %d", stompedRets);
        $display("Stomped Rets: %d", stompedRets);
        rasp <= rasp - stompedRets;
        rasp <= rasp - stompedRets;
    end
    end
    else if (stompedRet) begin
    else if (stompedRet) begin
        $display("Stomped Ret");
        $display("Stomped Ret");
        rasp <= rasp - 5'd1;
        rasp <= rasp - 5'd1;
    end
    end
*/
*/
end
end
 
 
endmodule
endmodule
 
 

powered by: WebSVN 2.1.0

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