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