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

Subversion Repositories altor32

[/] [altor32/] [trunk/] [rtl/] [cpu/] [altor32_lsu.v] - Rev 37

Compare with Previous | Blame | View Log

//-----------------------------------------------------------------
//                           AltOR32 
//                Alternative Lightweight OpenRisc 
//                            V2.1
//                     Ultra-Embedded.com
//                   Copyright 2011 - 2014
//
//               Email: admin@ultra-embedded.com
//
//                       License: LGPL
//-----------------------------------------------------------------
//
// Copyright (C) 2011 - 2014 Ultra-Embedded.com
//
// This source file may be used and distributed without         
// restriction provided that this copyright statement is not    
// removed from the file and that any derivative work contains  
// the original copyright notice and the associated disclaimer. 
//
// 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 2.1 of the License, or (at your option) any   
// later version.
//
// This source 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 Lesser General Public License for more 
// details.
//
// You should have received a copy of the GNU Lesser General    
// Public License along with this source; if not, write to the 
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
// Boston, MA  02111-1307  USA
//-----------------------------------------------------------------
 
//-----------------------------------------------------------------
// Module: Load / Store Unit
//-----------------------------------------------------------------
module altor32_lsu
(
    // Current instruction
    input               opcode_valid_i /*verilator public*/,
    input [7:0]         opcode_i /*verilator public*/,
 
    // Load / Store pending
    input               load_pending_i /*verilator public*/,
    input               store_pending_i /*verilator public*/,
 
    // Load dest register
    input [4:0]         rd_load_i /*verilator public*/,
 
    // Load insn in WB stage
    input               load_wb_i /*verilator public*/,
 
    // Memory status
    input               mem_access_i /*verilator public*/,
    input               mem_ack_i /*verilator public*/,
 
    // Load / store still pending
    output reg          load_pending_o /*verilator public*/,
    output reg          store_pending_o /*verilator public*/,
 
    // Insert load result into pipeline
    output reg          write_result_o /*verilator public*/,
 
    // Stall pipeline due load / store / insert
    output reg          stall_o /*verilator public*/
);
 
//-----------------------------------------------------------------
// Includes
//-----------------------------------------------------------------
`include "altor32_defs.v"
`include "altor32_funcs.v"
 
//-------------------------------------------------------------------
// Outstanding memory access logic
//-------------------------------------------------------------------
reg inst_load_r;
reg inst_store_r;
 
always @ *
begin
 
    load_pending_o   = load_pending_i;
    store_pending_o  = store_pending_i;
    stall_o          = 1'b0;
    write_result_o   = 1'b0;
 
    // Is this instruction a load or store?
    inst_load_r     = is_load_operation(opcode_i);
    inst_store_r    = is_store_operation(opcode_i);
 
    // Store operation just completed?
    if (store_pending_o & mem_ack_i & ~mem_access_i)
    begin
    `ifdef CONF_CORE_DEBUG       
        $display("   Store operation now completed");
    `endif            
        store_pending_o = 1'b0;
    end
 
    // Load just completed (and result ready in-time for writeback stage)?
    if (load_pending_o & mem_ack_i & ~mem_access_i & load_wb_i)
    begin
        // Load complete
        load_pending_o       = 1'b0;
 
    `ifdef CONF_CORE_DEBUG
        $display("   Load operation completed in writeback stage");
    `endif
    end
    // Load just completed (later than writeback stage)?
    else if (load_pending_o & mem_ack_i & ~mem_access_i)
    begin
    `ifdef CONF_CORE_DEBUG        
        $display("   Load operation completed later than writeback stage");
    `endif
 
        // Valid target register?
        if (rd_load_i != 5'b00000)
        begin
    `ifdef CONF_CORE_DEBUG            
            $display("   Load result now ready for R%d", rd_load_i);
    `endif
            // Stall instruction and write load result to pipeline
            stall_o         = opcode_valid_i;
            write_result_o  = 1'b1;
        end
        else
        begin
    `ifdef CONF_CORE_DEBUG            
            $display("   Load result ready but not needed");
    `endif
        end
 
        // Load complete
        load_pending_o       = 1'b0;
    end       
 
    // If load or store in progress (and this instruction is valid)
    if ((load_pending_o | store_pending_o) & opcode_valid_i)
    begin
        // Load or store whilst memory bus busy
        if (inst_load_r | inst_store_r)
        begin
    `ifdef CONF_CORE_DEBUG            
            $display("   Data bus already busy, stall (load_pending_o=%d, store_pending_o=%d)",  load_pending_o, store_pending_o);
    `endif                
            // Stall!
            stall_o         = 1'b1; 
        end
    end
end
 
endmodule
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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