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

Subversion Repositories altor32

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

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

Rev 32 Rev 36
//-----------------------------------------------------------------
//-----------------------------------------------------------------
//                           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
//-----------------------------------------------------------------
//-----------------------------------------------------------------
//
//
// Copyright (C) 2011 - 2013 Ultra-Embedded.com
// Copyright (C) 2011 - 2013 Ultra-Embedded.com
//
//
// This source file may be used and distributed without         
// This source file may be used and distributed without         
// restriction provided that this copyright statement is not    
// restriction provided that this copyright statement is not    
// removed from the file and that any derivative work contains  
// removed from the file and that any derivative work contains  
// the original copyright notice and the associated disclaimer. 
// the original copyright notice and the associated disclaimer. 
//
//
// This source file is free software; you can redistribute it   
// This source file is free software; you can redistribute it   
// and/or modify it under the terms of the GNU Lesser General   
// and/or modify it under the terms of the GNU Lesser General   
// Public License as published by the Free Software Foundation; 
// Public License as published by the Free Software Foundation; 
// either version 2.1 of the License, or (at your option) any   
// either version 2.1 of the License, or (at your option) any   
// later version.
// later version.
//
//
// This source is distributed in the hope that it will be       
// This source is distributed in the hope that it will be       
// useful, but WITHOUT ANY WARRANTY; without even the implied   
// useful, but WITHOUT ANY WARRANTY; without even the implied   
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      
// PURPOSE.  See the GNU Lesser General Public License for more 
// PURPOSE.  See the GNU Lesser General Public License for more 
// details.
// details.
//
//
// You should have received a copy of the GNU Lesser General    
// You should have received a copy of the GNU Lesser General    
// Public License along with this source; if not, write to the 
// Public License along with this source; if not, write to the 
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
// Boston, MA  02111-1307  USA
// Boston, MA  02111-1307  USA
//-----------------------------------------------------------------
//-----------------------------------------------------------------
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// Module - Data Cache Memory Interface
// Module - Data Cache Memory Interface
//-----------------------------------------------------------------
//-----------------------------------------------------------------
module altor32_dcache_mem_if
module altor32_dcache_mem_if
(
(
    input               clk_i /*verilator public*/,
    input               clk_i /*verilator public*/,
    input               rst_i /*verilator public*/,
    input               rst_i /*verilator public*/,
 
 
    // Cache interface
    // Cache interface
    input [31:0]        address_i /*verilator public*/,
    input [31:0]        address_i /*verilator public*/,
    input [31:0]        data_i /*verilator public*/,
    input [31:0]        data_i /*verilator public*/,
    output reg [31:0]   data_o /*verilator public*/,
    output reg [31:0]   data_o /*verilator public*/,
    input               fill_i /*verilator public*/,
    input               fill_i /*verilator public*/,
    input               evict_i /*verilator public*/,
    input               evict_i /*verilator public*/,
    input  [31:0]       evict_addr_i /*verilator public*/,
    input  [31:0]       evict_addr_i /*verilator public*/,
    input               rd_single_i /*verilator public*/,
    input               rd_single_i /*verilator public*/,
    input [3:0]         wr_single_i /*verilator public*/,
    input [3:0]         wr_single_i /*verilator public*/,
    output reg          done_o /*verilator public*/,
    output reg          done_o /*verilator public*/,
 
 
    // Cache memory (fill/evict)
    // Cache memory (fill/evict)
    output reg [31:2]   cache_addr_o /*verilator public*/,
    output reg [31:2]   cache_addr_o /*verilator public*/,
    output reg [31:0]   cache_data_o /*verilator public*/,
    output reg [31:0]   cache_data_o /*verilator public*/,
    input      [31:0]   cache_data_i /*verilator public*/,
    input      [31:0]   cache_data_i /*verilator public*/,
    output reg          cache_wr_o /*verilator public*/,
    output reg          cache_wr_o /*verilator public*/,
 
 
    // Memory interface (slave)
    // Memory interface (slave)
    output reg [31:0]   mem_addr_o /*verilator public*/,
    output reg [31:0]   mem_addr_o /*verilator public*/,
    input [31:0]        mem_data_i /*verilator public*/,
    input [31:0]        mem_data_i /*verilator public*/,
    output reg [31:0]   mem_data_o /*verilator public*/,
    output reg [31:0]   mem_data_o /*verilator public*/,
    output reg [2:0]    mem_cti_o /*verilator public*/,
    output reg [2:0]    mem_cti_o /*verilator public*/,
    output reg          mem_cyc_o /*verilator public*/,
    output reg          mem_cyc_o /*verilator public*/,
    output reg          mem_stb_o /*verilator public*/,
    output reg          mem_stb_o /*verilator public*/,
    output reg          mem_we_o /*verilator public*/,
    output reg          mem_we_o /*verilator public*/,
    output reg [3:0]    mem_sel_o /*verilator public*/,
    output reg [3:0]    mem_sel_o /*verilator public*/,
    input               mem_stall_i/*verilator public*/,
    input               mem_stall_i/*verilator public*/,
    input               mem_ack_i/*verilator public*/
    input               mem_ack_i/*verilator public*/
);
);
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// Params
// Params
//-----------------------------------------------------------------
//-----------------------------------------------------------------
parameter CACHE_LINE_SIZE_WIDTH     = 5;                         /* 5-bits -> 32 entries */
parameter CACHE_LINE_SIZE_WIDTH     = 5;                         /* 5-bits -> 32 entries */
parameter CACHE_LINE_WORDS_IDX_MAX  = CACHE_LINE_SIZE_WIDTH - 2; /* 3-bit -> 8 words */
parameter CACHE_LINE_WORDS_IDX_MAX  = CACHE_LINE_SIZE_WIDTH - 2; /* 3-bit -> 8 words */
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// Registers / Wires
// Registers / Wires
//-----------------------------------------------------------------
//-----------------------------------------------------------------
 
 
reg [31:CACHE_LINE_SIZE_WIDTH]  line_address;
reg [31:CACHE_LINE_SIZE_WIDTH]  line_address;
 
 
reg [CACHE_LINE_WORDS_IDX_MAX-1:0] response_idx;
reg [CACHE_LINE_WORDS_IDX_MAX-1:0] response_idx;
 
 
reg [CACHE_LINE_WORDS_IDX_MAX-1:0]  request_idx;
reg [CACHE_LINE_WORDS_IDX_MAX-1:0]  request_idx;
wire [CACHE_LINE_WORDS_IDX_MAX-1:0] next_request_idx = request_idx + 1'b1;
wire [CACHE_LINE_WORDS_IDX_MAX-1:0] next_request_idx = request_idx + 1'b1;
 
 
reg [CACHE_LINE_WORDS_IDX_MAX-1:0]  cache_idx;
reg [CACHE_LINE_WORDS_IDX_MAX-1:0]  cache_idx;
wire [CACHE_LINE_WORDS_IDX_MAX-1:0] next_cache_idx = cache_idx + 1'b1;
wire [CACHE_LINE_WORDS_IDX_MAX-1:0] next_cache_idx = cache_idx + 1'b1;
 
 
 
 
// Current state
// Current state
parameter STATE_IDLE        = 0;
parameter STATE_IDLE        = 0;
parameter STATE_FETCH       = 1;
parameter STATE_FETCH       = 1;
parameter STATE_WRITE_SETUP = 2;
parameter STATE_WRITE_SETUP = 2;
parameter STATE_WRITE       = 3;
parameter STATE_WRITE       = 3;
parameter STATE_WRITE_WAIT  = 4;
parameter STATE_WRITE_WAIT  = 4;
parameter STATE_MEM_SINGLE  = 5;
parameter STATE_MEM_SINGLE  = 5;
parameter STATE_FETCH_WAIT  = 6;
parameter STATE_FETCH_WAIT  = 6;
 
 
reg [3:0] state;
reg [3:0] state;
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// Next State Logic
// Next State Logic
//-----------------------------------------------------------------
//-----------------------------------------------------------------
reg [3:0] next_state_r;
reg [3:0] next_state_r;
always @ *
always @ *
begin
begin
    next_state_r = state;
    next_state_r = state;
 
 
    case (state)
    case (state)
    //-----------------------------------------
    //-----------------------------------------
    // IDLE
    // IDLE
    //-----------------------------------------
    //-----------------------------------------
    STATE_IDLE :
    STATE_IDLE :
    begin
    begin
        // Perform cache evict (write)     
        // Perform cache evict (write)     
        if (evict_i)
        if (evict_i)
            next_state_r    = STATE_WRITE_SETUP;
            next_state_r    = STATE_WRITE_SETUP;
        // Perform cache fill (read)
        // Perform cache fill (read)
        else if (fill_i)
        else if (fill_i)
            next_state_r    = STATE_FETCH;
            next_state_r    = STATE_FETCH;
        // Read/Write single
        // Read/Write single
        else if (rd_single_i | (|wr_single_i))
        else if (rd_single_i | (|wr_single_i))
            next_state_r    = STATE_MEM_SINGLE;
            next_state_r    = STATE_MEM_SINGLE;
    end
    end
    //-----------------------------------------
    //-----------------------------------------
    // FETCH - Fetch line from memory
    // FETCH - Fetch line from memory
    //-----------------------------------------
    //-----------------------------------------
    STATE_FETCH :
    STATE_FETCH :
    begin
    begin
        // Line fetch complete?
        // Line fetch complete?
        if (~mem_stall_i && request_idx == {CACHE_LINE_WORDS_IDX_MAX{1'b1}})
        if (~mem_stall_i && request_idx == {CACHE_LINE_WORDS_IDX_MAX{1'b1}})
            next_state_r    = STATE_FETCH_WAIT;
            next_state_r    = STATE_FETCH_WAIT;
    end
    end
    //-----------------------------------------
    //-----------------------------------------
    // FETCH_WAIT - Wait for read responses
    // FETCH_WAIT - Wait for read responses
    //-----------------------------------------
    //-----------------------------------------
    STATE_FETCH_WAIT:
    STATE_FETCH_WAIT:
    begin
    begin
        // Read from memory complete
        // Read from memory complete
        if (mem_ack_i && response_idx == {CACHE_LINE_WORDS_IDX_MAX{1'b1}})
        if (mem_ack_i && response_idx == {CACHE_LINE_WORDS_IDX_MAX{1'b1}})
            next_state_r = STATE_IDLE;
            next_state_r = STATE_IDLE;
    end
    end
    //-----------------------------------------
    //-----------------------------------------
    // WRITE_SETUP - Wait for data from cache
    // WRITE_SETUP - Wait for data from cache
    //-----------------------------------------
    //-----------------------------------------
    STATE_WRITE_SETUP :
    STATE_WRITE_SETUP :
        next_state_r    = STATE_WRITE;
        next_state_r    = STATE_WRITE;
    //-----------------------------------------
    //-----------------------------------------
    // WRITE - Write word to memory
    // WRITE - Write word to memory
    //-----------------------------------------
    //-----------------------------------------
    STATE_WRITE :
    STATE_WRITE :
    begin
    begin
        // Line write complete?
        // Line write complete?
        if (~mem_stall_i && request_idx == {CACHE_LINE_WORDS_IDX_MAX{1'b1}})
        if (~mem_stall_i && request_idx == {CACHE_LINE_WORDS_IDX_MAX{1'b1}})
            next_state_r = STATE_WRITE_WAIT;
            next_state_r = STATE_WRITE_WAIT;
        // Fetch next word for line
        // Fetch next word for line
        else if (~mem_stall_i | ~mem_stb_o)
        else if (~mem_stall_i | ~mem_stb_o)
            next_state_r = STATE_WRITE_SETUP;
            next_state_r = STATE_WRITE_SETUP;
    end
    end
    //-----------------------------------------
    //-----------------------------------------
    // WRITE_WAIT - Wait for write to complete
    // WRITE_WAIT - Wait for write to complete
    //-----------------------------------------
    //-----------------------------------------
    STATE_WRITE_WAIT:
    STATE_WRITE_WAIT:
    begin
    begin
        // Write to memory complete
        // Write to memory complete
        if (mem_ack_i && response_idx == {CACHE_LINE_WORDS_IDX_MAX{1'b1}})
        if (mem_ack_i && response_idx == {CACHE_LINE_WORDS_IDX_MAX{1'b1}})
            next_state_r = STATE_IDLE;
            next_state_r = STATE_IDLE;
    end
    end
    //-----------------------------------------
    //-----------------------------------------
    // MEM_SINGLE - Single access to memory
    // MEM_SINGLE - Single access to memory
    //-----------------------------------------
    //-----------------------------------------
    STATE_MEM_SINGLE:
    STATE_MEM_SINGLE:
    begin
    begin
        // Data ready from memory?
        // Data ready from memory?
        if (mem_ack_i)
        if (mem_ack_i)
            next_state_r  = STATE_IDLE;
            next_state_r  = STATE_IDLE;
    end
    end
    default:
    default:
        ;
        ;
   endcase
   endcase
end
end
 
 
// Update state
// Update state
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)
        state   <= STATE_IDLE;
        state   <= STATE_IDLE;
   else
   else
        state   <= next_state_r;
        state   <= next_state_r;
end
end
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// Control logic
// Control 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)
   begin
   begin
        line_address    <= {32-CACHE_LINE_SIZE_WIDTH{1'b0}};
        line_address    <= {32-CACHE_LINE_SIZE_WIDTH{1'b0}};
        done_o          <= 1'b0;
        done_o          <= 1'b0;
        data_o          <= 32'h00000000;
        data_o          <= 32'h00000000;
   end
   end
   else
   else
   begin
   begin
        done_o          <= 1'b0;
        done_o          <= 1'b0;
 
 
        case (state)
        case (state)
 
 
            //-----------------------------------------
            //-----------------------------------------
            // IDLE
            // IDLE
            //-----------------------------------------
            //-----------------------------------------
            STATE_IDLE :
            STATE_IDLE :
            begin
            begin
                // Perform cache evict (write)     
                // Perform cache evict (write)     
                if (evict_i)
                if (evict_i)
                    line_address <= evict_addr_i[31:CACHE_LINE_SIZE_WIDTH];
                    line_address <= evict_addr_i[31:CACHE_LINE_SIZE_WIDTH];
                // Perform cache fill (read)
                // Perform cache fill (read)
                else if (fill_i)
                else if (fill_i)
                    line_address <= address_i[31:CACHE_LINE_SIZE_WIDTH];
                    line_address <= address_i[31:CACHE_LINE_SIZE_WIDTH];
            end
            end
            //-----------------------------------------
            //-----------------------------------------
            // FETCH/WRITE_WAIT - Wait for oustanding responses
            // FETCH/WRITE_WAIT - Wait for oustanding responses
            //-----------------------------------------
            //-----------------------------------------
            STATE_WRITE_WAIT,
            STATE_WRITE_WAIT,
            STATE_FETCH_WAIT:
            STATE_FETCH_WAIT:
            begin
            begin
                // Write to memory complete
                // Write to memory complete
                if (mem_ack_i)
                if (mem_ack_i)
                begin
                begin
                    // Line write complete?
                    // Line write complete?
                    if (response_idx == {CACHE_LINE_WORDS_IDX_MAX{1'b1}})
                    if (response_idx == {CACHE_LINE_WORDS_IDX_MAX{1'b1}})
                        done_o      <= 1'b1;
                        done_o      <= 1'b1;
                end
                end
            end
            end
            //-----------------------------------------
            //-----------------------------------------
            // MEM_SINGLE - Single access to memory
            // MEM_SINGLE - Single access to memory
            //-----------------------------------------
            //-----------------------------------------
            STATE_MEM_SINGLE:
            STATE_MEM_SINGLE:
            begin
            begin
                // Data ready from memory?
                // Data ready from memory?
                if (mem_ack_i)
                if (mem_ack_i)
                begin
                begin
                    data_o      <= mem_data_i;
                    data_o      <= mem_data_i;
                    done_o      <= 1'b1;
                    done_o      <= 1'b1;
                end
                end
            end
            end
            default:
            default:
                ;
                ;
           endcase
           endcase
   end
   end
end
end
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// Cache Read / Write
// Cache Read / Write
//-----------------------------------------------------------------
//-----------------------------------------------------------------
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)
   begin
   begin
        cache_addr_o    <= 30'h00000000;
        cache_addr_o    <= 30'h00000000;
        cache_data_o    <= 32'h00000000;
        cache_data_o    <= 32'h00000000;
        cache_wr_o      <= 1'b0;
        cache_wr_o      <= 1'b0;
 
 
        cache_idx       <= {CACHE_LINE_WORDS_IDX_MAX{1'b0}};
        cache_idx       <= {CACHE_LINE_WORDS_IDX_MAX{1'b0}};
   end
   end
   else
   else
   begin
   begin
        cache_wr_o      <= 1'b0;
        cache_wr_o      <= 1'b0;
 
 
        case (state)
        case (state)
 
 
            //-----------------------------------------
            //-----------------------------------------
            // IDLE
            // IDLE
            //-----------------------------------------
            //-----------------------------------------
            STATE_IDLE :
            STATE_IDLE :
            begin
            begin
                cache_idx       <= {CACHE_LINE_WORDS_IDX_MAX{1'b0}};
                cache_idx       <= {CACHE_LINE_WORDS_IDX_MAX{1'b0}};
 
 
                // Perform cache evict (write)     
                // Perform cache evict (write)     
                if (evict_i)
                if (evict_i)
                begin
                begin
                    // Read data from cache
                    // Read data from cache
                    cache_addr_o  <= {evict_addr_i[31:CACHE_LINE_SIZE_WIDTH], {CACHE_LINE_WORDS_IDX_MAX{1'b0}}};
                    cache_addr_o  <= {evict_addr_i[31:CACHE_LINE_SIZE_WIDTH], {CACHE_LINE_WORDS_IDX_MAX{1'b0}}};
                end
                end
            end
            end
            //-----------------------------------------
            //-----------------------------------------
            // FETCH - Fetch line from memory
            // FETCH - Fetch line from memory
            //-----------------------------------------
            //-----------------------------------------
            STATE_FETCH,
            STATE_FETCH,
            STATE_FETCH_WAIT:
            STATE_FETCH_WAIT:
            begin
            begin
                // Data ready from memory?
                // Data ready from memory?
                if (mem_ack_i)
                if (mem_ack_i)
                begin
                begin
                    // Write data into cache
                    // Write data into cache
                    cache_addr_o    <= {line_address, cache_idx};
                    cache_addr_o    <= {line_address, cache_idx};
                    cache_data_o    <= mem_data_i;
                    cache_data_o    <= mem_data_i;
                    cache_wr_o      <= 1'b1;
                    cache_wr_o      <= 1'b1;
 
 
                    cache_idx       <= next_cache_idx;
                    cache_idx       <= next_cache_idx;
                end
                end
            end
            end
            //-----------------------------------------
            //-----------------------------------------
            // WRITE - Write word to memory
            // WRITE - Write word to memory
            //-----------------------------------------
            //-----------------------------------------
            STATE_WRITE_SETUP:
            STATE_WRITE_SETUP:
            begin
            begin
 
 
            end
            end
            STATE_WRITE,
            STATE_WRITE,
            STATE_WRITE_WAIT:
            STATE_WRITE_WAIT:
            begin
            begin
                if (~mem_stall_i | ~mem_stb_o)
                if (~mem_stall_i | ~mem_stb_o)
                begin
                begin
                    // Setup next word read from cache
                    // Setup next word read from cache
                    cache_addr_o <= {line_address, next_cache_idx};
                    cache_addr_o <= {line_address, next_cache_idx};
                    cache_idx    <= next_cache_idx;
                    cache_idx    <= next_cache_idx;
                end
                end
            end
            end
            default:
            default:
                ;
                ;
           endcase
           endcase
   end
   end
end
end
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// Request
// Request
//-----------------------------------------------------------------
//-----------------------------------------------------------------
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)
   begin
   begin
        mem_addr_o      <= 32'h00000000;
        mem_addr_o      <= 32'h00000000;
        mem_data_o      <= 32'h00000000;
        mem_data_o      <= 32'h00000000;
        mem_sel_o       <= 4'h0;
        mem_sel_o       <= 4'h0;
        mem_cti_o       <= 3'b0;
        mem_cti_o       <= 3'b0;
        mem_stb_o       <= 1'b0;
        mem_stb_o       <= 1'b0;
        mem_we_o        <= 1'b0;
        mem_we_o        <= 1'b0;
        request_idx     <= {CACHE_LINE_WORDS_IDX_MAX{1'b0}};
        request_idx     <= {CACHE_LINE_WORDS_IDX_MAX{1'b0}};
   end
   end
   else
   else
   begin
   begin
        if (~mem_stall_i)
        if (~mem_stall_i)
        begin
        begin
            mem_stb_o   <= 1'b0;
            mem_stb_o   <= 1'b0;
 
 
            // TMP
            // TMP
            if (mem_cti_o == 3'b111)
            if (mem_cti_o == 3'b111)
            begin
            begin
                //mem_addr_o      <= 32'h00000000;
                //mem_addr_o      <= 32'h00000000;
                mem_data_o      <= 32'h00000000;
                mem_data_o      <= 32'h00000000;
                mem_sel_o       <= 4'h0;
                mem_sel_o       <= 4'h0;
                mem_cti_o       <= 3'b0;
                mem_cti_o       <= 3'b0;
                mem_stb_o       <= 1'b0;
                mem_stb_o       <= 1'b0;
                mem_we_o        <= 1'b0;
                mem_we_o        <= 1'b0;
            end
            end
        end
        end
 
 
        case (state)
        case (state)
 
 
            //-----------------------------------------
            //-----------------------------------------
            // IDLE
            // IDLE
            //-----------------------------------------
            //-----------------------------------------
            STATE_IDLE :
            STATE_IDLE :
            begin
            begin
                request_idx     <= {CACHE_LINE_WORDS_IDX_MAX{1'b0}};
                request_idx     <= {CACHE_LINE_WORDS_IDX_MAX{1'b0}};
 
 
                // Perform cache evict (write)     
                // Perform cache evict (write)     
                if (evict_i)
                if (evict_i)
                begin
                begin
 
 
                end
                end
                // Perform cache fill (read)
                // Perform cache fill (read)
                else if (fill_i)
                else if (fill_i)
                begin
                begin
                    // Start fetch from memory
                    // Start fetch from memory
                    mem_addr_o   <= {address_i[31:CACHE_LINE_SIZE_WIDTH], {CACHE_LINE_SIZE_WIDTH{1'b0}}};
                    mem_addr_o   <= {address_i[31:CACHE_LINE_SIZE_WIDTH], {CACHE_LINE_SIZE_WIDTH{1'b0}}};
                    mem_data_o   <= 32'h00000000;
                    mem_data_o   <= 32'h00000000;
                    mem_sel_o    <= 4'b1111;
                    mem_sel_o    <= 4'b1111;
                    mem_cti_o    <= 3'b010;
                    mem_cti_o    <= 3'b010;
                    mem_stb_o    <= 1'b1;
                    mem_stb_o    <= 1'b1;
                    mem_we_o     <= 1'b0;
                    mem_we_o     <= 1'b0;
 
 
                    request_idx  <= next_request_idx;
                    request_idx  <= next_request_idx;
                end
                end
                // Read single
                // Read single
                else if (rd_single_i)
                else if (rd_single_i)
                begin
                begin
                    // Start fetch from memory
                    // Start fetch from memory
                    mem_addr_o   <= address_i;
                    mem_addr_o   <= address_i;
                    mem_data_o   <= 32'h00000000;
                    mem_data_o   <= 32'h00000000;
                    mem_sel_o    <= 4'b1111;
                    mem_sel_o    <= 4'b1111;
                    mem_cti_o    <= 3'b111;
                    mem_cti_o    <= 3'b111;
                    mem_stb_o    <= 1'b1;
                    mem_stb_o    <= 1'b1;
                    mem_we_o     <= 1'b0;
                    mem_we_o     <= 1'b0;
                end
                end
                // Write single
                // Write single
                else if (|wr_single_i)
                else if (|wr_single_i)
                begin
                begin
                    // Start fetch from memory
                    // Start fetch from memory
                    mem_addr_o   <= address_i;
                    mem_addr_o   <= address_i;
                    mem_data_o   <= data_i;
                    mem_data_o   <= data_i;
                    mem_sel_o    <= wr_single_i;
                    mem_sel_o    <= wr_single_i;
                    mem_cti_o    <= 3'b111;
                    mem_cti_o    <= 3'b111;
                    mem_stb_o    <= 1'b1;
                    mem_stb_o    <= 1'b1;
                    mem_we_o     <= 1'b1;
                    mem_we_o     <= 1'b1;
                end
                end
            end
            end
            //-----------------------------------------
            //-----------------------------------------
            // FETCH - Fetch line from memory
            // FETCH - Fetch line from memory
            //-----------------------------------------
            //-----------------------------------------
            STATE_FETCH :
            STATE_FETCH :
            begin
            begin
                // Previous request accepted?
                // Previous request accepted?
                if (~mem_stall_i)
                if (~mem_stall_i)
                begin
                begin
                    // Fetch next word for line
                    // Fetch next word for line
                    mem_addr_o <= {line_address, request_idx, 2'b00};
                    mem_addr_o <= {line_address, request_idx, 2'b00};
                    mem_stb_o  <= 1'b1;
                    mem_stb_o  <= 1'b1;
 
 
                    if (request_idx == {CACHE_LINE_WORDS_IDX_MAX{1'b1}})
                    if (request_idx == {CACHE_LINE_WORDS_IDX_MAX{1'b1}})
                        mem_cti_o <= 3'b111;
                        mem_cti_o <= 3'b111;
 
 
                    request_idx <= next_request_idx;
                    request_idx <= next_request_idx;
                end
                end
            end
            end
            //-----------------------------------------
            //-----------------------------------------
            // WRITE - Write word to memory
            // WRITE - Write word to memory
            //-----------------------------------------
            //-----------------------------------------
            STATE_WRITE :
            STATE_WRITE :
            begin
            begin
                // Memory interface can request command?
                // Memory interface can request command?
                if (~mem_stall_i | ~mem_stb_o)
                if (~mem_stall_i | ~mem_stb_o)
                begin
                begin
                    // Write data into memory from cache
                    // Write data into memory from cache
                    mem_addr_o   <= {line_address, request_idx, 2'b00};
                    mem_addr_o   <= {line_address, request_idx, 2'b00};
                    mem_data_o   <= cache_data_i;
                    mem_data_o   <= cache_data_i;
                    mem_sel_o    <= 4'b1111;
                    mem_sel_o    <= 4'b1111;
                    mem_stb_o    <= 1'b1;
                    mem_stb_o    <= 1'b1;
                    mem_we_o     <= 1'b1;
                    mem_we_o     <= 1'b1;
 
 
                    if (request_idx == {CACHE_LINE_WORDS_IDX_MAX{1'b1}})
                    if (request_idx == {CACHE_LINE_WORDS_IDX_MAX{1'b1}})
                        mem_cti_o <= 3'b111;
                        mem_cti_o <= 3'b111;
                    else
                    else
                        mem_cti_o <= 3'b010;
                        mem_cti_o <= 3'b010;
 
 
                    request_idx <= next_request_idx;
                    request_idx <= next_request_idx;
                end
                end
            end
            end
            default:
            default:
                ;
                ;
           endcase
           endcase
   end
   end
end
end
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// Memory Response Counter
// Memory Response Counter
//-----------------------------------------------------------------
//-----------------------------------------------------------------
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)
        response_idx    <= {CACHE_LINE_WORDS_IDX_MAX{1'b0}};
        response_idx    <= {CACHE_LINE_WORDS_IDX_MAX{1'b0}};
   else
   else
   begin
   begin
        case (state)
        case (state)
 
 
            //-----------------------------------------
            //-----------------------------------------
            // IDLE
            // IDLE
            //-----------------------------------------
            //-----------------------------------------
            STATE_IDLE :
            STATE_IDLE :
            begin
            begin
                response_idx    <= {CACHE_LINE_WORDS_IDX_MAX{1'b0}};
                response_idx    <= {CACHE_LINE_WORDS_IDX_MAX{1'b0}};
            end
            end
            //-----------------------------------------
            //-----------------------------------------
            // FETCH - Fetch line from memory
            // FETCH - Fetch line from memory
            //-----------------------------------------
            //-----------------------------------------
            STATE_FETCH,
            STATE_FETCH,
            STATE_FETCH_WAIT :
            STATE_FETCH_WAIT :
            begin
            begin
                // Data ready from memory?
                // Data ready from memory?
                if (mem_ack_i)
                if (mem_ack_i)
                    response_idx <= response_idx + 1'b1;
                    response_idx <= response_idx + 1'b1;
            end
            end
            //-----------------------------------------
            //-----------------------------------------
            // WRITE_WAIT - Wait for write to complete
            // WRITE_WAIT - Wait for write to complete
            //-----------------------------------------
            //-----------------------------------------
            STATE_WRITE,
            STATE_WRITE,
            STATE_WRITE_SETUP,
            STATE_WRITE_SETUP,
            STATE_WRITE_WAIT:
            STATE_WRITE_WAIT:
            begin
            begin
                // Write to memory complete
                // Write to memory complete
                if (mem_ack_i)
                if (mem_ack_i)
                    response_idx <= response_idx + 1'b1;
                    response_idx <= response_idx + 1'b1;
            end
            end
            default:
            default:
                ;
                ;
           endcase
           endcase
   end
   end
end
end
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// CYC_O
// CYC_O
//-----------------------------------------------------------------
//-----------------------------------------------------------------
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)
        mem_cyc_o       <= 1'b0;
        mem_cyc_o       <= 1'b0;
   else
   else
   begin
   begin
        case (state)
        case (state)
 
 
            //-----------------------------------------
            //-----------------------------------------
            // IDLE
            // IDLE
            //-----------------------------------------
            //-----------------------------------------
            STATE_IDLE :
            STATE_IDLE :
            begin
            begin
                // Perform cache evict (write)     
                // Perform cache evict (write)     
                if (evict_i)
                if (evict_i)
                begin
                begin
 
 
                end
                end
                // Perform cache fill (read)
                // Perform cache fill (read)
                else if (fill_i)
                else if (fill_i)
                    mem_cyc_o    <= 1'b1;
                    mem_cyc_o    <= 1'b1;
                // Read single
                // Read single
                else if (rd_single_i)
                else if (rd_single_i)
                    mem_cyc_o    <= 1'b1;
                    mem_cyc_o    <= 1'b1;
                // Write single
                // Write single
                else if (|wr_single_i)
                else if (|wr_single_i)
                    mem_cyc_o    <= 1'b1;
                    mem_cyc_o    <= 1'b1;
            end
            end
            //-----------------------------------------
            //-----------------------------------------
            // FETCH - Fetch line from memory
            // FETCH - Fetch line from memory
            //-----------------------------------------
            //-----------------------------------------
            STATE_FETCH :
            STATE_FETCH :
            begin
            begin
                // Data ready from memory?
                // Data ready from memory?
                if (mem_ack_i && response_idx == {CACHE_LINE_WORDS_IDX_MAX{1'b1}})
                if (mem_ack_i && response_idx == {CACHE_LINE_WORDS_IDX_MAX{1'b1}})
                    mem_cyc_o   <= 1'b0;
                    mem_cyc_o   <= 1'b0;
            end
            end
            //-----------------------------------------
            //-----------------------------------------
            // WRITE - Write word to memory
            // WRITE - Write word to memory
            //-----------------------------------------
            //-----------------------------------------
            STATE_WRITE :
            STATE_WRITE :
            begin
            begin
                // Write data into memory from cache
                // Write data into memory from cache
                mem_cyc_o    <= 1'b1;
                mem_cyc_o    <= 1'b1;
            end
            end
            //-----------------------------------------
            //-----------------------------------------
            // FETCH/WRITE_WAIT - Wait for responses
            // FETCH/WRITE_WAIT - Wait for responses
            //-----------------------------------------
            //-----------------------------------------
            STATE_WRITE_WAIT,
            STATE_WRITE_WAIT,
            STATE_FETCH_WAIT:
            STATE_FETCH_WAIT:
            begin
            begin
                // Write to memory complete
                // Write to memory complete
                if (mem_ack_i && response_idx == {CACHE_LINE_WORDS_IDX_MAX{1'b1}})
                if (mem_ack_i && response_idx == {CACHE_LINE_WORDS_IDX_MAX{1'b1}})
                    mem_cyc_o   <= 1'b0;
                    mem_cyc_o   <= 1'b0;
            end
            end
            //-----------------------------------------
            //-----------------------------------------
            // MEM_SINGLE - Single access to memory
            // MEM_SINGLE - Single access to memory
            //-----------------------------------------
            //-----------------------------------------
            STATE_MEM_SINGLE:
            STATE_MEM_SINGLE:
            begin
            begin
                // Data ready from memory?
                // Data ready from memory?
                if (mem_ack_i)
                if (mem_ack_i)
                    mem_cyc_o   <= 1'b0;
                    mem_cyc_o   <= 1'b0;
            end
            end
            default:
            default:
                ;
                ;
           endcase
           endcase
   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.