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

Subversion Repositories forwardcom

[/] [forwardcom/] [trunk/] [call_stack.sv] - Blame information for rev 103

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 13 Agner
//////////////////////////////////////////////////////////////////////////////////
2
// Engineer: Agner Fog
3
//
4
// Create Date:       2020-05-05
5
// Last modified:     2021-07-27
6
// Module Name:       call_stack
7
// Project Name:      ForwardCom soft core
8
// Target Devices:    Artix 7
9
// Tool Versions:     Vivado v. 2020.1
10
// License:           CERN-OHL-W v. 2 or later
11
// Description:       on-chip call stack. controls call and return instructions
12
//
13
//////////////////////////////////////////////////////////////////////////////////
14
`include "defines.vh"
15
 
16
// call stack, 1024*32 bits, used for function return addresses but not for parameters or local data
17
// On call instruction: put return address on push_data and set call_e high for one clock cycle.
18
// On return instruction: the return address is pre-loaded into pop_data for early read.
19
// Set return_e high for one clock cycle to make next return address ready.
20
 
21
// It is not allowed to have call_e and return_e in the same clock cycle.
22
// It is not allowed to have return_e in the first clock cycle after call_e
23
// or return_e. This is not a problem in the current design because consecutive
24
// jump, call, and return instructions are delayed by the access time to the code cache.
25
// If the design is improved with more efficient branch prediction then it may be
26
// necessary to add precautions to prevent a return_e signal in the first clock cycle
27
// after another return_e or call_e.
28
 
29
module call_stack (
30
    input clock,                                 // clock
31
    input clock_enable,                          // clock enable. Used when single-stepping
32
    input reset,                                 // clock enable. Used when single-stepping
33
    input call_e,                                // Executing call instruction. push_data contains return address
34
    input return_e,                              // Executing return instruction. return address is available in advance on pop_data
35
    input  [`CODE_ADDR_WIDTH-1:0] push_data,     // Return address pushed here at call instruction
36
    output reg [`CODE_ADDR_WIDTH-1:0] pop_data,  // Return address popped here at return instruction
37
    output reg overflow                          // stack overflow or underflow or error
38
   );
39
 
40
// site of stack = 2**stack_pointer_bits
41
parameter integer stack_pointer_bits = `CALL_STACK_POINTER_BITS;
42
 
43
// stack ram, on-chip
44
reg [`CODE_ADDR_WIDTH-1:0] ram[0:(2**stack_pointer_bits)-1];
45
 
46
// call stack pointer
47
reg [stack_pointer_bits-1:0] call_stack_pointer = 0;
48
 
49
// call and return operations = push and pop of function return addresses:
50
always_ff @(posedge clock) if (clock_enable) begin
51
    overflow <= 0;
52
    if (reset) begin
53
        call_stack_pointer <= 0;
54
        pop_data <= 0;
55
        overflow <= 0;
56
 
57
    end else if (call_e) begin
58
        if (call_stack_pointer == (2**stack_pointer_bits)-1 || return_e) begin
59
            overflow <= 1;                          // overflow or other error
60
        end else begin
61
            ram[call_stack_pointer] <= push_data;   // push return address on stack
62
            pop_data <= push_data;                  // make next return address ready
63
            call_stack_pointer <= call_stack_pointer + 1;
64
        end
65
 
66
    end else if (return_e) begin
67
        if (call_stack_pointer == 0) begin
68
            overflow <= 1;                          // stack underflow
69
        end else if (call_stack_pointer == 1) begin
70
            pop_data <= 0;                          // stack empty
71
            call_stack_pointer <= call_stack_pointer - 1;
72
        end else begin
73
            pop_data <= ram[call_stack_pointer-2];  // make next return address ready
74
            call_stack_pointer <= call_stack_pointer - 1;
75
        end
76
    end
77
end
78
 
79
endmodule

powered by: WebSVN 2.1.0

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