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

Subversion Repositories aor3000

[/] [aor3000/] [trunk/] [sim/] [aoR3000/] [main_linux.cpp] - Rev 2

Compare with Previous | Blame | View Log

/*
 * This file is subject to the terms and conditions of the BSD License. See
 * the file "LICENSE" in the main directory of this archive for more details.
 *
 * Copyright (C) 2014 Aleksander Osman
 */
 
#include <cstdio>
#include <cstdlib>
 
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
 
#include "VaoR3000.h"
#include "VaoR3000_aoR3000.h"
#include "VaoR3000_pipeline_rf.h"
#include "VaoR3000_pipeline_if.h"
#include "VaoR3000_pipeline_mem.h"
#include "VaoR3000_block_muldiv.h"
#include "VaoR3000_memory_tlb_ram.h"
#include "VaoR3000_block_cp0.h"
#include "VaoR3000_pipeline_exe.h"
#include "VaoR3000_model_true_dual_ram__W32_WB4.h"
#include "VaoR3000_model_simple_dual_ram__W20_WB5.h"
 
#include "verilated.h"
#include "verilated_vcd_c.h"
 
#include "shared_mem.h"
 
//------------------------------------------------------------------------------
 
volatile shared_mem_t *shared_ptr = NULL;
 
//------------------------------------------------------------------------------
 
void usleep_or_finish() {
    if(shared_ptr->test_finished) {
        printf("Finishing.\n");
        exit(0);
    }
    usleep(1);
}
 
//128MB
#define MAX_MEMORY   0x08000000
#define RESET_VECTOR 0x1FC00000
 
//------------------------------------------------------------------------------
 
int main(int argc, char **argv) {
 
    //map shared memory
    int fd = open("./../tester/shared_mem.dat", O_RDWR, S_IRUSR | S_IWUSR);
 
    if(fd == -1) {
        perror("open() failed for shared_mem.dat");
        return -1;
    }
 
    shared_ptr = (shared_mem_t *)mmap(NULL, sizeof(shared_mem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
 
    if(shared_ptr == MAP_FAILED) {
        perror("mmap() failed");
        close(fd);
        return -2;
    }
 
    //--------------------------------------------------------------------------
 
    Verilated::commandArgs(argc, argv);
 
    Verilated::traceEverOn(true);
    VerilatedVcdC* tracer = new VerilatedVcdC;
 
    VaoR3000 *top = new VaoR3000();
    top->trace (tracer, 99);
    //tracer->rolloverMB(1000000);
    tracer->open("aoR3000.vcd");
 
    bool dump_enabled = false;
 
    //reset
    vluint64_t halfcycle = 0;
 
    top->clk = 0; top->rst_n = 1; top->eval(); if(dump_enabled) { tracer->dump(halfcycle); } halfcycle++;
    top->clk = 0; top->rst_n = 0; top->eval(); if(dump_enabled) { tracer->dump(halfcycle); } halfcycle++;
    top->rst_n = 1;
 
    printf("Waiting for initialize..."); fflush(stdout);
    while(shared_ptr->proc_ao.initialize_do == false) usleep_or_finish();
 
    shared_ptr->proc_ao.initialize_do = false;
    printf("done\n");
 
    //--------------------------------------------------------------------------
 
    uint32 event_counter = 0;
 
    struct read_t {
        uint32 count;
        uint32 byteenable;
        uint32 address;
    };
    read_t read[5];
    uint32 read_list_count = sizeof(read) / sizeof(read_t);
    memset(read, 0, sizeof(read));
 
    bool   stall_wait = false;
    bool   stall_state = false;
 
    bool   is_exception_waiting = false;
 
    while(!Verilated::gotFinish()) {
 
        //---------------------------------------------------------------------- avalon master
 
        top->avm_waitrequest   = 0;
        top->avm_readdatavalid = 0;
        top->avm_readdata      = 0;
 
        if(top->avm_read) {
            bool found = false;
            for(uint32 i=0; i<read_list_count; i++) {
                if(read[i].count == 0) {
                    read[i].address    = top->avm_address & 0xFFFFFFFC;
                    read[i].byteenable = top->avm_byteenable;
                    read[i].count      = top->avm_burstcount;
 
                    found = true;
                    break;
                }
            }
            if(found == false) {
                printf("[aoR3000]: read fatal error: too many reads.\n");
                exit(-1);
            }
        }
        else if(read[0].count > 0) {
            top->avm_readdatavalid = 1;
 
            if(read[0].address < MAX_MEMORY) {
                top->avm_readdata = shared_ptr->mem.ints[read[0].address/4];
            }
            else if(read[0].address >= RESET_VECTOR && read[0].address < RESET_VECTOR + sizeof(shared_ptr->reset_vector)) {
                top->avm_readdata = shared_ptr->reset_vector[(read[0].address - RESET_VECTOR)/4];
            }
            else {
                shared_ptr->proc_ao.read_address    = read[0].address & 0xFFFFFFFC;
                shared_ptr->proc_ao.read_byteenable = read[0].byteenable;
                shared_ptr->proc_ao.read_do         = true;
 
                while(shared_ptr->proc_ao.read_do) usleep_or_finish();
 
                top->avm_readdata = shared_ptr->proc_ao.read_data;
            }
            read[0].address += 4;
            read[0].count--;
 
            if(read[0].count == 0) {
                memmove(&read[0], &read[1], sizeof(read) - sizeof(read_t));
            }
        }
 
        //----------------------------------------------------------------------
 
        if(stall_state == true) stall_state = ((top->v->pipeline_mem_inst->__PVT__mem_stall & 1) == 0)? false : true;
 
        uint32 cmd = top->v->pipeline_mem_inst->__PVT__mem_cmd & 0x7F;
 
        bool stall_start = cmd != 0   && stall_state == true;
        bool stall_end   = stall_wait && stall_state == false;
 
        uint32 was_instruction = ((cmd != 0) && stall_state == false) || stall_end;
        uint32 was_pc          = top->v->pipeline_mem_inst->__PVT__mem_pc_plus4;
 
        if(stall_start) {
            stall_wait = true;
        }
        else if(stall_end) {
            stall_wait = false;
        }
 
        if(stall_state == false) stall_state = ((top->v->pipeline_mem_inst->__PVT__mem_stall & 1) == 0)? false : true;
 
        //----------------------------------------------------------------------
 
        bool dump_enabled = false; //event_counter > 40565500;
 
        //---------------------------------------------------------------------- interrupt
 
        bool irq2_enable = ((was_instruction && stall_end == false && (event_counter + 1) == shared_ptr->irq2_at_event)) || ((event_counter + 1) > shared_ptr->irq2_at_event);
        bool irq3_enable = ((was_instruction && stall_end == false && (event_counter + 1) == shared_ptr->irq3_at_event)) || ((event_counter + 1) > shared_ptr->irq3_at_event);
        top->interrupt_vector = ((irq2_enable)? 1 : 0) | ((irq3_enable)? 2 : 0);
 
        if(dump_enabled) {
            printf("[%d]: ena2: %d ena3: %d cmd: %d at2: %d at3: %d stall_state: %d stall_start: %d stall_end: %d\n",
                event_counter, (uint32)irq2_enable, (uint32)irq3_enable, cmd, shared_ptr->irq2_at_event, shared_ptr->irq3_at_event, stall_state, (uint32)stall_start, (uint32)stall_end);
            fflush(stdout);
        }
 
        //---------------------------------------------------------------------- clock
        top->clk = 0;
        top->eval();
 
        if(dump_enabled) tracer->dump(halfcycle);
        halfcycle++;
 
        top->clk = 1;
        top->eval();
 
        if(dump_enabled) tracer->dump(halfcycle);
        halfcycle++;
 
        tracer->flush();
 
        //----------------------------------------------------------------------
        if(top->avm_write) {
            if(top->avm_burstcount != 1) {
                printf("[avalon master error]: top->avm_burstcount(%d) != 1\n", top->avm_burstcount);
                exit(-1);
            }
 
            uint32 mask = 0;
            uint32 byteena = top->avm_byteenable;
            for(uint32 i=0; i<4; i++) {
                if(byteena & 1) mask |= (0xFF << (i*8));
                byteena >>= 1;
            }
 
            shared_ptr->proc_ao.write_address    = top->avm_address & 0xFFFFFFFC;
            shared_ptr->proc_ao.write_byteenable = top->avm_byteenable;
            shared_ptr->proc_ao.write_data       = top->avm_writedata & mask;
            shared_ptr->proc_ao.write_do         = true;
 
            while(shared_ptr->proc_ao.write_do) usleep_or_finish();
        }
 
        uint32 is_exception = (top->v->pipeline_if_inst->__PVT__exc_waiting & 1);
 
        //interrupt after stalled instruction ignored
 
        if((is_exception && was_instruction && (event_counter > 0 || halfcycle >= (4*2))) || was_instruction) {
 
            if(dump_enabled) { printf("inc: %d, exception: %d\n", event_counter, is_exception); fflush(stdout); }
 
            shared_ptr->proc_ao.report.counter = event_counter;
 
            if(shared_ptr->check_at_event == event_counter) {
                shared_ptr->proc_ao.check_do = true;
 
                while(shared_ptr->proc_ao.check_do) usleep_or_finish();
            }
 
            event_counter++;
        }
 
        is_exception_waiting = is_exception;
    }
 
    top->final();
    delete top;
    return 0;
}
 
//------------------------------------------------------------------------------
 
/*
module aoR3000(
    input               clk,
    input               rst_n,
 
    //
    input       [5:0]   interrupt_vector,
 
    //
    output      [31:0]  avm_address,
    output      [31:0]  avm_writedata,
    output      [3:0]   avm_byteenable,
    output      [2:0]   avm_burstcount,
    output              avm_write,
    output              avm_read,
 
    input               avm_waitrequest,
    input               avm_readdatavalid,
    input       [31:0]  avm_readdata
);
*/
 
//------------------------------------------------------------------------------
 

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.