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

Subversion Repositories altor32

[/] [altor32/] [trunk/] [rtl/] [cpu/] [altor32_icache.v] - Diff between revs 32 and 36

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 32 Rev 36
Line 1... Line 1...
//-----------------------------------------------------------------
//-----------------------------------------------------------------
//                           AltOR32 
//                           AltOR32 
//                Alternative Lightweight OpenRisc 
//                Alternative Lightweight OpenRisc 
//                            V2.0
//                            V2.1
//                     Ultra-Embedded.com
//                     Ultra-Embedded.com
//                   Copyright 2011 - 2013
//                   Copyright 2011 - 2014
//
//
//               Email: admin@ultra-embedded.com
//               Email: admin@ultra-embedded.com
//
//
//                       License: LGPL
//                       License: LGPL
//-----------------------------------------------------------------
//-----------------------------------------------------------------
Line 53... Line 53...
    input [31:0]                pc_i /*verilator public*/,
    input [31:0]                pc_i /*verilator public*/,
    output [31:0]               instruction_o /*verilator public*/,
    output [31:0]               instruction_o /*verilator public*/,
    output                      valid_o /*verilator public*/,
    output                      valid_o /*verilator public*/,
    input                       invalidate_i /*verilator public*/,
    input                       invalidate_i /*verilator public*/,
 
 
    // Status
 
    output                      miss_o /*verilator public*/,
 
    output                      busy_o /*verilator public*/,
 
 
 
    // Memory interface
    // Memory interface
    output reg [31:0]           wbm_addr_o /*verilator public*/,
    output reg [31:0]           wbm_addr_o /*verilator public*/,
    input [31:0]                wbm_dat_i /*verilator public*/,
    input [31:0]                wbm_dat_i /*verilator public*/,
    output reg [2:0]            wbm_cti_o /*verilator public*/,
    output reg [2:0]            wbm_cti_o /*verilator public*/,
    output reg                  wbm_cyc_o /*verilator public*/,
    output reg                  wbm_cyc_o /*verilator public*/,
Line 110... Line 106...
// Tag address
// Tag address
wire [CACHE_LINE_ADDR_WIDTH-1:0] tag_entry;
wire [CACHE_LINE_ADDR_WIDTH-1:0] tag_entry;
 
 
// Data memory read / write
// Data memory read / write
wire [CACHE_DWIDTH-1:0]         cache_address_rd;
wire [CACHE_DWIDTH-1:0]         cache_address_rd;
reg [CACHE_DWIDTH-1:0]          cache_address_wr;
wire [CACHE_DWIDTH-1:0]         cache_address_wr;
reg [31:0]                      cache_data_in;
reg [31:0]                      cache_data_in;
reg                             cache_wr;
wire                            cache_wr;
 
 
// Word currently being fetched within a line
// Word currently being fetched within a line
reg [CACHE_LINE_SIZE_WIDTH-3:0] mem_fetch_word;
reg [CACHE_LINE_SIZE_WIDTH-3:0] mem_fetch_word;
reg [CACHE_LINE_SIZE_WIDTH-3:0] mem_resp_idx;
reg [CACHE_LINE_SIZE_WIDTH-3:0] mem_resp_idx;
 
 
Line 135... Line 131...
 
 
// Current state
// Current state
parameter STATE_CHECK       = 0;
parameter STATE_CHECK       = 0;
parameter STATE_FETCH       = 1;
parameter STATE_FETCH       = 1;
parameter STATE_WAIT        = 2;
parameter STATE_WAIT        = 2;
parameter STATE_WAIT2       = 3;
parameter STATE_FLUSH       = 3;
parameter STATE_FLUSH       = 4;
 
reg [3:0]                   state;
reg [3:0]                   state;
 
 
// Tag address from input PC or flopped version of it
// Tag address from input PC or flopped version of it
assign tag_entry        = (state != STATE_CHECK) ?
assign tag_entry        = (state != STATE_CHECK) ?
                          miss_pc[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:CACHE_LINE_SIZE_WIDTH] :
                          miss_pc[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:CACHE_LINE_SIZE_WIDTH] :
Line 148... Line 143...
 
 
// Cache read address
// Cache read address
assign cache_address_rd   = pc_i[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:2];
assign cache_address_rd   = pc_i[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:2];
 
 
// Cache miss output if requested PC is not in the tag memory
// Cache miss output if requested PC is not in the tag memory
assign miss_o             = (!tag_data_out[CACHE_TAG_VALID_BIT] ||
wire miss                 = (!tag_data_out[CACHE_TAG_VALID_BIT] ||
                            (last_pc[CACHE_TAG_ADDR_HIGH:CACHE_TAG_ADDR_LOW] != tag_data_out[14:0])) ? 1'b1: 1'b0;
                            (last_pc[CACHE_TAG_ADDR_HIGH:CACHE_TAG_ADDR_LOW] != tag_data_out[14:0])) ? 1'b1: 1'b0;
 
 
// Cache output valid
 
assign valid_o            = !miss_o && !busy_o;
 
 
 
// Stall the CPU if cache state machine is not idle!
// Stall the CPU if cache state machine is not idle!
assign busy_o             = (state == STATE_CHECK & ~read_while_busy) ? 1'b0 : 1'b1;
wire busy                 = (state == STATE_CHECK & ~read_while_busy) ? 1'b0 : 1'b1;
 
 
 
// Cache output valid
 
assign valid_o            = !miss && !busy;
 
 
// Final word to fetch from memory
// Final word to fetch from memory
wire mem_fetch_final_word = (mem_fetch_word == {CACHE_LINE_WORDS_IDX_MAX{1'b1}});
wire mem_fetch_final_word = (mem_fetch_word == {CACHE_LINE_WORDS_IDX_MAX{1'b1}});
 
 
// Flushing: Last line to flush
// Flushing: Last line to flush
wire flush_final_line     = (flush_addr == {CACHE_LINE_ADDR_WIDTH{1'b0}});
wire flush_final_line     = (flush_addr == {CACHE_LINE_ADDR_WIDTH{1'b0}});
 
 
// Is this a cache miss?
// Is this a cache miss?
wire cache_miss           = (miss_o &&               // Tag lookup failed
wire cache_miss           = (miss &&               // Tag lookup failed
                            !initial_fetch &&        // NOT initial fetch after reset
                            !initial_fetch &&        // NOT initial fetch after reset
                            !rd_i &&                 // NOT new read request cycle
                            !rd_i &&                 // NOT new read request cycle
                            !read_while_busy &&      // NOT pending read whilst busy
                            !read_while_busy &&      // NOT pending read whilst busy
                            !flush_req &&            // NOT flush request
                            !flush_req &&            // NOT flush request
                            !invalidate_i);
                            !invalidate_i);
Line 219... Line 214...
    end
    end
    //-----------------------------------------
    //-----------------------------------------
    // WAIT - Wait cycle
    // WAIT - Wait cycle
    //-----------------------------------------
    //-----------------------------------------
    STATE_WAIT :
    STATE_WAIT :
        // Allow extra wait state to handle write & read collision    
 
        next_state_r = STATE_WAIT2;
 
    //-----------------------------------------
 
    // WAIT2 - Wait cycle
 
    //-----------------------------------------
 
    STATE_WAIT2 :
 
        next_state_r = STATE_CHECK;
        next_state_r = STATE_CHECK;
    default:
    default:
        ;
        ;
   endcase
   endcase
end
end
Line 354... Line 343...
       endcase
       endcase
   end
   end
end
end
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// Cache Data Write
 
//-----------------------------------------------------------------
 
always @ (posedge rst_i or posedge clk_i )
 
begin
 
   if (rst_i == 1'b1)
 
   begin
 
        cache_address_wr<= {CACHE_DWIDTH{1'b0}};
 
        cache_data_in    <= 32'h00000000;
 
        cache_wr        <= 1'b0;
 
   end
 
   else
 
   begin
 
        cache_wr        <= 1'b0;
 
 
 
        // FETCH - Fetch row from memory
 
        if (state == STATE_FETCH)
 
        begin
 
            // Data ready from memory?
 
            if (wbm_ack_i)
 
            begin
 
                // Write data into cache
 
                cache_address_wr <= {miss_pc[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:CACHE_LINE_SIZE_WIDTH], mem_resp_idx};
 
                cache_data_in    <= wbm_dat_i;
 
                cache_wr         <= 1'b1;
 
            end
 
        end
 
   end
 
end
 
 
 
//-----------------------------------------------------------------
 
// Flush Logic
// Flush Logic
//-----------------------------------------------------------------
//-----------------------------------------------------------------
always @ (posedge rst_i or posedge clk_i )
always @ (posedge rst_i or posedge clk_i )
begin
begin
   if (rst_i == 1'b1)
   if (rst_i == 1'b1)
Line 517... Line 476...
        STATE_FLUSH :
        STATE_FLUSH :
        begin
        begin
            // Fetch current PC line again
            // Fetch current PC line again
            if (flush_final_line)
            if (flush_final_line)
            begin
            begin
 
                if (read_while_busy)
 
                    wbm_addr_o      <= {miss_pc[31:CACHE_LINE_SIZE_WIDTH], {CACHE_LINE_SIZE_WIDTH{1'b0}}};
 
                else
                wbm_addr_o      <= {pc_i[31:CACHE_LINE_SIZE_WIDTH], {CACHE_LINE_SIZE_WIDTH{1'b0}}};
                wbm_addr_o      <= {pc_i[31:CACHE_LINE_SIZE_WIDTH], {CACHE_LINE_SIZE_WIDTH{1'b0}}};
 
 
                // Incrementing linear burst
                // Incrementing linear burst
                wbm_cti_o       <= 3'b010;
                wbm_cti_o       <= 3'b010;
 
 
Line 669... Line 631...
 
 
    // Data write port
    // Data write port
    .bclk_i(clk_i),
    .bclk_i(clk_i),
    .badr_i(cache_address_wr),
    .badr_i(cache_address_wr),
    .bdat_o(/*open*/),
    .bdat_o(/*open*/),
    .bdat_i(cache_data_in),
    .bdat_i(wbm_dat_i),
    .bwr_i(cache_wr)
    .bwr_i(cache_wr)
);
);
 
 
 
// Write to cache on wishbone response
 
assign cache_address_wr = {miss_pc[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:CACHE_LINE_SIZE_WIDTH], mem_resp_idx};
 
 
 
assign cache_wr = (state == STATE_FETCH) & wbm_ack_i;
 
 
endmodule
endmodule
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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