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

Subversion Repositories forwardcom

[/] [forwardcom/] [trunk/] [code_memory.sv] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 Agner
//////////////////////////////////////////////////////////////////////////////////
2
// Engineer: Agner Fog
3
//
4
// Create Date:       2020-05-05
5
// Last modified:     2021-08-02
6
// Module Name:       code_cache
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 code memory or code cache
12
//
13
//////////////////////////////////////////////////////////////////////////////////
14
`include "defines.vh"
15
 
16
// It takes two clock cycles to fetch data from on-chip ram,
17
// Attempts to fetch in one cycle, using negedge or latch failed for timing reasons
18
 
19
 
20
// code memory, 1024*64 bits,
21
module code_memory (
22
    input clock,                                 // clock
23
    input clock_enable,                          // clock enable. Used when single-stepping
24
    input read_enable,                           // read enable when fetching code
25
    input [7:0] write_enable,                    // write enable for each byte separately when writing code. must be 0x0F or 0xF0 or 0xFF
26
    input [`COMMON_ADDR_WIDTH-1:0] write_addr_in,// Address lines when writing to code memory
27
    input [63:0] write_data_in,                  // Data lines when writing to code memory
28
    input [`CODE_ADDR_WIDTH-2:0] read_addr_in,   // Address for reading from code memory
29
    output reg [`CODE_DATA_WIDTH-1:0] data_out,  // Data out
30
 
31
    // outputs for debugger:
32
    output reg [31:0] debug_out           // debug information
33
);
34
 
35
// code ram
36
reg [`CODE_DATA_WIDTH-1:0] ram[0:(2**(`CODE_ADDR_WIDTH-1)-1)];
37
// (attempt to split this into 32-bit lines failed to implement as ram block)
38
 
39
logic [`COMMON_ADDR_WIDTH-4:0] write_address_hi;
40
//logic [`DATA_ADDR_WIDTH-4:0] write_address_hi;
41
//logic [2:0] address_lo; // not used
42
logic write_address_valid;
43
 
44
always_comb begin
45
//    write_address_hi = write_addr_in[`COMMON_ADDR_WIDTH-1:3] - {1'b1,`CODE_ADDR_START'b0}; // index to 64-bit lines
46
    write_address_hi = write_addr_in[`COMMON_ADDR_WIDTH-1:3] - {1'b1,{(`CODE_ADDR_START-3){1'b0}}}; // index to 64-bit lines
47
    write_address_valid = write_addr_in[`COMMON_ADDR_WIDTH-1:`CODE_ADDR_START] != 0;       // code address space
48
end
49
 
50
/*
51
Calculation of loader address:
52
Code memory starts at address 2**CODE_ADDR_START = 32kB = 0x8000
53
Code memory size = 2**(CODE_ADDR_WIDTH+2) = 64kB = 0x10000
54
Code memory end = code memory start + code memory size = 0x18000
55
Max loader size = 2kB = 0x800 bytes
56
Loader start address = code memory end - max loader size
57
Each line in code ram is CODE_DATA_WIDTH = 64 bits = 8 bytes
58
Loader start line = (code memory size - max loader size) / line size
59
*/
60
parameter max_loader_size   = `MAX_LOADER_SIZE << 2;   // loader size in bytes
61
parameter code_memory_start = 2**`CODE_ADDR_START;
62
parameter code_memory_size  = 2**(`CODE_ADDR_WIDTH+2);
63
parameter code_memory_end   = code_memory_start + code_memory_size;
64
parameter loader_start_address = code_memory_end - max_loader_size;
65
parameter loader_start_relative = code_memory_size - max_loader_size;
66
parameter loader_start_line = loader_start_relative / (`CODE_DATA_WIDTH >> 3);
67
 
68
generate if (`LOADER_FILE != "")
69
    initial begin
70
        // insert loader code
71
        $readmemh(`LOADER_FILE, ram, loader_start_line);
72
    end
73
endgenerate
74
 
75
 
76
// code ram read and write process
77
always_ff @(posedge clock) if (clock_enable) begin
78
 
79
    // Write data to code RAM when loading program code
80
    if (write_address_valid) begin  // write address is in code section
81
        if (write_enable[0]) begin
82
            ram[write_address_hi][31:0] <= write_data_in[31:0];
83
        end
84
        if (write_enable[4]) begin
85
            ram[write_address_hi][63:32] <= write_data_in[63:32];
86
        end
87
    end
88
 
89
    // Read from code ram when executing
90
    if (read_enable) begin
91
        data_out <= ram[read_addr_in];
92
    end
93
 
94
    // Output for debugger
95
    debug_out[23:0] <= write_address_hi;
96
    debug_out[28] <= write_address_valid;
97
 
98
end
99
 
100
endmodule

powered by: WebSVN 2.1.0

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