mirror of
https://github.com/openhwgroup/cva5.git
synced 2025-04-20 03:57:18 -04:00
further verilator testbench changes
This commit is contained in:
parent
6c301cf236
commit
63eb64ed8b
12 changed files with 391 additions and 107 deletions
|
@ -122,7 +122,7 @@ module load_store_unit (
|
|||
assign input_fifo.data_in = ls_inputs;
|
||||
assign input_fifo.push = issue.new_request;
|
||||
assign issue.ready = 1;//As FIFO depth is the same as MAX_INFLIGHT_COUNT
|
||||
assign input_fifo.pop = issue_request | gc_issue_flush;
|
||||
assign input_fifo.pop = issue_request;
|
||||
assign stage1 = input_fifo.data_out;
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
|
|
@ -96,7 +96,7 @@ module l2_arbiter (
|
|||
assign requests_in[i].is_amo = request[i].is_amo;
|
||||
assign requests_in[i].amo_type_or_burst_size = request[i].amo_type_or_burst_size;
|
||||
assign requests_in[i].sub_id = request[i].sub_id;
|
||||
assign input_fifos[i].data_in = reqests_in[i];
|
||||
assign input_fifos[i].data_in = requests_in[i];
|
||||
|
||||
assign input_fifos[i].pop = input_fifos[i].valid & arb.grantee_v[i] & ~mem_addr_fifo.full;
|
||||
|
||||
|
|
|
@ -160,7 +160,7 @@ module taiga_full_simulation ();
|
|||
integer output_file;
|
||||
integer output_file2;
|
||||
|
||||
assign l2[1].request = 0;
|
||||
//assign l2[1].request = 0;
|
||||
assign l2[1].request_push = 0;
|
||||
assign l2[1].wr_data_push = 0;
|
||||
assign l2[1].inv_ack = l2[1].inv_valid;
|
||||
|
@ -392,7 +392,6 @@ module taiga_full_simulation ();
|
|||
$fwrite(output_file, "instruction_issued_dec %d\n",instruction_issued_dec);
|
||||
$fwrite(output_file, "branch_misspredict %d\n",branch_misspredict);
|
||||
$fwrite(output_file, "return_misspredict %d\n",return_misspredict);
|
||||
$fwrite(output_file, "wb_mux_contention %d\n",wb_mux_contention);
|
||||
$fwrite(output_file, "rs1_forwarding_needed %d\n",rs1_forwarding_needed);
|
||||
$fwrite(output_file, "rs2_forwarding_needed %d\n",rs2_forwarding_needed);
|
||||
$fwrite(output_file, "rs1_OR_rs2_forwarding_needed %d\n",rs1_forwarding_needed + rs2_forwarding_needed);
|
||||
|
@ -416,33 +415,30 @@ module taiga_full_simulation ();
|
|||
rs1_and_rs2_forwarding_needed = 0;
|
||||
branch_misspredict = 0;
|
||||
return_misspredict = 0;
|
||||
wb_mux_contention = 0;
|
||||
end
|
||||
|
||||
if (tr.operand_stall)
|
||||
if (tr.events.operand_stall)
|
||||
operand_stall <= operand_stall + 1;
|
||||
if (tr.unit_stall)
|
||||
if (tr.events.unit_stall)
|
||||
unit_stall <= unit_stall + 1;
|
||||
if (tr.no_id_stall)
|
||||
if (tr.events.no_id_stall)
|
||||
no_id_stall <= no_id_stall + 1;
|
||||
if (tr.no_instruction_stall)
|
||||
if (tr.events.no_instruction_stall)
|
||||
no_instruction_stall <= no_instruction_stall + 1;
|
||||
if (tr.other_stall)
|
||||
if (tr.events.other_stall)
|
||||
other_stall <= other_stall + 1;
|
||||
if (tr.instruction_issued_dec)
|
||||
if (tr.events.instruction_issued_dec)
|
||||
instruction_issued_dec <= instruction_issued_dec + 1;
|
||||
if (tr.rs1_forwarding_needed)
|
||||
if (tr.events.rs1_forwarding_needed)
|
||||
rs1_forwarding_needed <= rs1_forwarding_needed + 1;
|
||||
if (tr.rs2_forwarding_needed)
|
||||
if (tr.events.rs2_forwarding_needed)
|
||||
rs2_forwarding_needed <= rs2_forwarding_needed + 1;
|
||||
if (tr.rs1_and_rs2_forwarding_needed)
|
||||
if (tr.events.rs1_and_rs2_forwarding_needed)
|
||||
rs1_and_rs2_forwarding_needed <= rs1_and_rs2_forwarding_needed + 1;
|
||||
if (tr.branch_misspredict)
|
||||
if (tr.events.branch_misspredict)
|
||||
branch_misspredict <= branch_misspredict + 1;
|
||||
if (tr.return_misspredict)
|
||||
if (tr.events.return_misspredict)
|
||||
return_misspredict <= return_misspredict + 1;
|
||||
if (tr.wb_mux_contention)
|
||||
wb_mux_contention <= wb_mux_contention + 1;
|
||||
end
|
||||
|
||||
|
||||
|
|
44
test_benches/verilator/SimMem.cc
Normal file
44
test_benches/verilator/SimMem.cc
Normal file
|
@ -0,0 +1,44 @@
|
|||
#include <sstream>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include "SimMem.h"
|
||||
|
||||
|
||||
|
||||
SimMem::SimMem(std::ifstream& program, uint32_t mem_size) : mem_size(mem_size) {
|
||||
memory = new uint32_t[mem_size*256]();//mem_size in KB
|
||||
address_mask = (mem_size*256) - 1; //mask to prevent any out-of-bounds array access. Assumes power-of-two memory size
|
||||
|
||||
std::string line;
|
||||
for (int i =0; (i < mem_size*256) && (std::getline(program, line)); i++) {
|
||||
memory[i] = std::stoul(line, 0, 16);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32_t SimMem::read(uint32_t addr) {
|
||||
return memory[addr & address_mask];
|
||||
}
|
||||
|
||||
void SimMem::write(uint32_t addr, uint32_t data, uint32_t be) {
|
||||
uint32_t write_mask, old_word;
|
||||
|
||||
write_mask = 0;
|
||||
|
||||
if (be & 0x1)
|
||||
write_mask |= 0x000000FFL;
|
||||
if (be & 0x2)
|
||||
write_mask |= 0x0000FF00L;
|
||||
if (be & 0x4)
|
||||
write_mask |= 0x00FF0000L;
|
||||
if (be & 0x8)
|
||||
write_mask |= 0xFF000000L;
|
||||
|
||||
old_word = memory[addr & address_mask];
|
||||
memory[addr & address_mask] = (old_word & ~write_mask) | (data & write_mask);
|
||||
}
|
||||
|
||||
SimMem::~SimMem() {
|
||||
delete[] memory;
|
||||
}
|
40
test_benches/verilator/SimMem.h
Normal file
40
test_benches/verilator/SimMem.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright © 2019 Eric Matthews, Lesley Shannon
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Initial code developed under the supervision of Dr. Lesley Shannon,
|
||||
* Reconfigurable Computing Lab, Simon Fraser University.
|
||||
*
|
||||
* Author(s):
|
||||
* Eric Matthews <ematthew@sfu.ca>
|
||||
*/
|
||||
|
||||
#ifndef SIMMEM_H
|
||||
#define SIMMEM_H
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
class SimMem {
|
||||
public:
|
||||
SimMem(std::ifstream& program, uint32_t mem_size);
|
||||
~SimMem();
|
||||
void write (uint32_t addr, uint32_t data, uint32_t be);
|
||||
uint32_t read (uint32_t addr);
|
||||
private:
|
||||
uint32_t mem_size;
|
||||
uint32_t *memory;
|
||||
uint32_t address_mask;
|
||||
};
|
||||
#endif
|
|
@ -23,6 +23,7 @@
|
|||
#include <iostream>
|
||||
#include "TaigaTracer.h"
|
||||
|
||||
//#define TRACE_ON
|
||||
template <class TB>
|
||||
bool TaigaTracer<TB>::check_instruction_issued(uint32_t inst) {
|
||||
return (tb->instruction_data_dec == inst && tb->instruction_issued);
|
||||
|
@ -60,7 +61,8 @@ bool TaigaTracer<TB>::has_stalled() {
|
|||
|
||||
template <class TB>
|
||||
void TaigaTracer<TB>::reset_stats() {
|
||||
event_counters = { 0 };
|
||||
for (int i=0; i < numEvents; i++)
|
||||
event_counters[i] = 0;
|
||||
}
|
||||
|
||||
template <class TB>
|
||||
|
@ -83,11 +85,13 @@ void TaigaTracer<TB>::print_stats() {
|
|||
template <class TB>
|
||||
void TaigaTracer<TB>::reset() {
|
||||
tb->rst = 1;
|
||||
tb->eval();
|
||||
|
||||
for (int i=0; i <reset_length; i++)
|
||||
tick();
|
||||
|
||||
tb->rst = 0;
|
||||
reset_stats();
|
||||
}
|
||||
template <class TB>
|
||||
void TaigaTracer<TB>::set_log_file(std::ofstream* logFile) {
|
||||
|
@ -97,22 +101,41 @@ void TaigaTracer<TB>::set_log_file(std::ofstream* logFile) {
|
|||
template <class TB>
|
||||
void TaigaTracer<TB>::update_UART() {
|
||||
if (tb->write_uart) {
|
||||
std::cout << tb->uart_byte;
|
||||
std::cout << tb->uart_byte << std::flush;
|
||||
*logFile << tb->uart_byte;
|
||||
}
|
||||
}
|
||||
|
||||
template <class TB>
|
||||
void TaigaTracer<TB>::update_memory() {
|
||||
tb->instruction_bram_data_out = instruction_r;
|
||||
if (tb->instruction_bram_en)
|
||||
instruction_r = mem->read(tb->instruction_bram_addr);
|
||||
|
||||
tb->data_bram_data_out = data_out_r;
|
||||
if (tb->data_bram_en) {
|
||||
data_out_r = mem->read(tb->data_bram_addr);
|
||||
mem->write(tb->data_bram_addr, tb->data_bram_data_in, tb->data_bram_be);
|
||||
}
|
||||
}
|
||||
|
||||
template <class TB>
|
||||
void TaigaTracer<TB>::tick() {
|
||||
tb->eval();
|
||||
tb->clk = 1;
|
||||
tb->eval();
|
||||
tb->clk = 0;
|
||||
tb->eval();
|
||||
|
||||
cycle_count++;
|
||||
|
||||
update_stats();
|
||||
#ifdef TRACE_ON
|
||||
verilatorWaveformTracer->dump(vluint32_t(cycle_cout));
|
||||
#endif
|
||||
update_UART();
|
||||
update_memory();
|
||||
|
||||
#ifdef TRACE_ON
|
||||
verilatorWaveformTracer->dump(vluint32_t(cycle_count));
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class TB>
|
||||
|
@ -131,16 +154,17 @@ uint64_t TaigaTracer<TB>::get_cycle_count() {
|
|||
}
|
||||
|
||||
template <class TB>
|
||||
TaigaTracer<TB>::TaigaTracer() {
|
||||
TaigaTracer<TB>::TaigaTracer(std::ifstream& programFile) {
|
||||
#ifdef TRACE_ON
|
||||
Verilated::traceEverOn(true);
|
||||
#endif
|
||||
|
||||
mem = new SimMem(programFile, 128);
|
||||
tb = new TB;
|
||||
|
||||
tb->clk = 0;
|
||||
tb->eval();
|
||||
reset();
|
||||
instruction_r = mem->read(tb->instruction_bram_addr);
|
||||
data_out_r = 0;
|
||||
}
|
||||
|
||||
template <class TB>
|
||||
|
@ -149,5 +173,6 @@ TaigaTracer<TB>::~TaigaTracer() {
|
|||
verilatorWaveformTracer->flush();
|
||||
verilatorWaveformTracer->close();
|
||||
#endif
|
||||
delete mem;
|
||||
delete tb;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include "SimMem.h"
|
||||
|
||||
//#define TRACE_ON
|
||||
|
||||
#define COMPLIANCE_SIG_PHASE_NOP 0x00B00013U
|
||||
#define ERROR_TERMINATION_NOP 0x00F00013U
|
||||
|
@ -53,14 +56,12 @@ static const int numEvents = arraySize(eventNames);
|
|||
template <class TB>
|
||||
class TaigaTracer {
|
||||
public:
|
||||
TaigaTracer();
|
||||
TaigaTracer(std::ifstream& programFile);
|
||||
~TaigaTracer();
|
||||
bool check_instruction_issued(uint32_t inst);
|
||||
bool has_terminated();
|
||||
bool has_stalled();
|
||||
void print_stats();
|
||||
void update_stats();
|
||||
void update_UART();
|
||||
void reset_stats();
|
||||
void reset();
|
||||
void tick();
|
||||
|
@ -69,6 +70,7 @@ public:
|
|||
uint64_t get_cycle_count();
|
||||
private:
|
||||
TB *tb;
|
||||
SimMem *mem;
|
||||
#ifdef TRACE_ON
|
||||
VerilatedVcdC *verilatorWaveformTracer;
|
||||
#endif
|
||||
|
@ -78,6 +80,12 @@ private:
|
|||
int stall_count = 0;
|
||||
uint64_t cycle_count = 0;
|
||||
uint64_t event_counters[numEvents];
|
||||
|
||||
void update_stats();
|
||||
void update_UART();
|
||||
void update_memory();
|
||||
uint32_t instruction_r;
|
||||
uint32_t data_out_r;
|
||||
};
|
||||
|
||||
#include "TaigaTracer.cc"
|
||||
|
|
|
@ -1,33 +1,113 @@
|
|||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include "Vver_top.h"
|
||||
#include <fstream>
|
||||
#include "Vtaiga_full_sim.h"
|
||||
#include "verilated.h"
|
||||
#include "verilated_vcd_c.h"
|
||||
|
||||
using namespace std;
|
||||
//#define TRACE_ON
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
// Initialize Verilators variables
|
||||
Verilated::commandArgs(argc, argv);
|
||||
//Verilated::traceEverOn(true);
|
||||
#define COMPLIANCE_SIG_PHASE_NOP 0x00B00013U
|
||||
#define ERROR_TERMINATION_NOP 0x00F00013U
|
||||
#define SUCCESS_TERMINATION_NOP 0x00A00013U
|
||||
////////////////////////////////////////////////////
|
||||
//Trace Interface Counters
|
||||
|
||||
//VerilatedVcdC *tracer;
|
||||
//tracer = new VerilatedVcdC;
|
||||
// Create an instance of our module under test
|
||||
Vver_top *tb = new Vver_top;
|
||||
//tb->trace(tracer, 99);
|
||||
//tracer->open("sim_results.vcd");
|
||||
struct TaigaTrace {
|
||||
static void TaigaTrace::update_stats(Vtaiga_full_sim *tb) {
|
||||
operand_stall += tb->operand_stall;
|
||||
unit_stall += tb->unit_stall;
|
||||
no_id_stall += tb->no_id_stall;
|
||||
no_instruction_stall += tb->no_instruction_stall;
|
||||
other_stall += tb->other_stall;
|
||||
|
||||
instruction_issued_dec += tb->instruction_issued_dec;
|
||||
branch_misspredict += tb->branch_misspredict;
|
||||
return_misspredict += tb->return_misspredict;
|
||||
wb_mux_contention += tb->wb_mux_contention;
|
||||
|
||||
rs1_forwarding_needed += tb->rs1_forwarding_needed;
|
||||
rs2_forwarding_needed += tb->rs2_forwarding_needed;
|
||||
rs1_and_rs2_forwarding_needed += tb->rs1_and_rs2_forwarding_needed;
|
||||
}
|
||||
|
||||
static void print_stats(std::ostream& os) {
|
||||
os << " Taiga trace stats:\n";
|
||||
os << "--------------------------------------------------------------\n";
|
||||
os << " operand_stall: " << operand_stall << "\n";
|
||||
os << " unit_stall: " << unit_stall << "\n";
|
||||
os << " no_id_stall: " << no_id_stall << "\n";
|
||||
os << " no_instruction_stall: " << no_instruction_stall << "\n";
|
||||
os << " other_stall: " << other_stall << "\n";
|
||||
os << " instruction_issued_dec: " << instruction_issued_dec << "\n";
|
||||
os << " branch_misspredict: " << branch_misspredict << "\n";
|
||||
os << " return_misspredict: " << return_misspredict << "\n";
|
||||
os << " wb_mux_contention: " << wb_mux_contention << "\n";
|
||||
os << " rs1_forwarding_needed: " << rs1_forwarding_needed << "\n";
|
||||
os << " rs2_forwarding_needed: " << rs2_forwarding_needed << "\n";
|
||||
os << " rs1_OR_rs2_forwarding_needed: " << rs1_forwarding_needed + rs2_forwarding_needed << "\n";
|
||||
os << " rs1_AND_rs2_forwarding_needed: " << rs1_and_rs2_forwarding_needed << "\n";
|
||||
os << "--------------------------------------------------------------\n\n";
|
||||
}
|
||||
|
||||
static uint64_t operand_stall;
|
||||
static uint64_t unit_stall;
|
||||
static uint64_t no_id_stall;
|
||||
static uint64_t no_instruction_stall;
|
||||
static uint64_t other_stall;
|
||||
static uint64_t instruction_issued_dec;
|
||||
static uint64_t branch_misspredict;
|
||||
static uint64_t return_misspredict;
|
||||
static uint64_t wb_mux_contention;
|
||||
static uint64_t rs1_forwarding_needed;
|
||||
static uint64_t rs2_forwarding_needed;
|
||||
static uint64_t rs1_and_rs2_forwarding_needed;
|
||||
};
|
||||
Vtaiga_local_mem
|
||||
#define STALL_LIMIT 2000
|
||||
|
||||
bool hasStalled(Vtaiga_full_sim *tb) {
|
||||
if (!tb->instruction_issued_dec) {
|
||||
stall_cycles++;
|
||||
if (stall_cycles > STALL_LIMIT) {
|
||||
stall_cycles = 0;
|
||||
std::cout << "\n\nError!!!!\n";
|
||||
std::cout << "PC unchanged for at least " << STALL_LIMIT << " cycles!\n\n";
|
||||
return true;
|
||||
} else {
|
||||
stall_cycles = 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool complianceTestsLogPhase; //Log phase vs signature phase used for compliance tests
|
||||
bool checkForControlNOPs(Vtaiga_full_sim *tb) {
|
||||
//Custom nop to change to signature phase for compliance tests
|
||||
if (tb->instruction_data_dec == COMPLIANCE_SIG_PHASE_NOP && tb->instruction_issued_dec) {
|
||||
complianceTestsLogPhase = false;
|
||||
std::cout << "\n--------------------------------------------------------------\n";
|
||||
std::cout << " Signature\n";
|
||||
std::cout << "--------------------------------------------------------------\n";
|
||||
return false;
|
||||
}//Custom nop for error termination
|
||||
else if (tb->instruction_data_dec == ERROR_TERMINATION_NOP && tb->instruction_issued_dec) {
|
||||
std::cout << "\n\nError!!!!\n\n";
|
||||
}//Custom nop for regular termination
|
||||
else if (tb->instruction_data_dec == SUCCESS_TERMINATION_NOP && tb->instruction_issued_dec) {
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void performReset(Vtaiga_full_sim *tb, int numCycles) {
|
||||
int reset_count = 0;
|
||||
tb->rst = 1;
|
||||
|
||||
cout << "Starting test\n";
|
||||
cout << "******************************\n";
|
||||
int reset_count = 0;
|
||||
long int cycle_cout = 0;
|
||||
int stall_count = 0;
|
||||
tb->rst = 1;
|
||||
// Tick the clock until we are done
|
||||
while(!Verilated::gotFinish()) {
|
||||
if (reset_count > 64) {
|
||||
if (reset_count > numCycles) {
|
||||
tb->rst = 0;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
reset_count++;
|
||||
|
@ -37,35 +117,91 @@ int main(int argc, char **argv) {
|
|||
tb->eval();
|
||||
tb->clk = 0;
|
||||
tb->eval();
|
||||
|
||||
if (tb->write_uart) {
|
||||
cout << tb->uart_byte;
|
||||
}
|
||||
|
||||
if (tb->dec_instruction_r == 0x00100013U) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (tb->dec_advance_debug == 0) {
|
||||
stall_count++;
|
||||
} else {
|
||||
stall_count = 0;
|
||||
}
|
||||
|
||||
if (stall_count > 200) {
|
||||
cout << "Stall detected\n";
|
||||
break;
|
||||
}
|
||||
|
||||
//tracer->dump(vluint64_t(cycle_cout));
|
||||
cycle_cout++;
|
||||
}
|
||||
//tracer->flush();
|
||||
//tracer->close();
|
||||
cout << "******************************\n";
|
||||
cout << "Test Done\n";
|
||||
cout << "Simulated: " << cycle_cout << " cycles.";
|
||||
}
|
||||
|
||||
void handleUART(Vtaiga_full_sim *tb, bool logPhase, ofstream& logFile, ofstream& sigFile) {
|
||||
if (tb->write_uart) {
|
||||
std::cout << tb->uart_byte;
|
||||
if (logPhase) {
|
||||
logFile << tb->uart_byte;
|
||||
} else {
|
||||
sigFile << tb->uart_byte;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
int main(int argc, char **argv) {
|
||||
uint64_t cycle_cout = 0;
|
||||
TaigaTrace taigaTracer = { };//Zero initialize
|
||||
ofstream logFile, sigFile;
|
||||
|
||||
// Initialize Verilators variables
|
||||
Verilated::commandArgs(argc, argv);
|
||||
#ifdef TRACE_ON
|
||||
Verilated::traceEverOn(true);
|
||||
#endif
|
||||
|
||||
if (!argv[1]) {
|
||||
cout << "Missing log file name.\n";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!argv[2]) {
|
||||
cout << "Missing signature file name.\n";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
logFile.open (argv[1]);
|
||||
sigFile.open (argv[2]);
|
||||
// Create an instance of our module under test
|
||||
Vtaiga_full_sim *tb = new Vtaiga_full_sim;
|
||||
|
||||
#ifdef TRACE_ON
|
||||
VerilatedVcdC *verilatorWaveformTracer;
|
||||
verilatorWaveformTracer = new VerilatedVcdC;
|
||||
tb->trace(verilatorWaveformTracer, 99);
|
||||
verilatorWaveformTracer->open("/data/sim-logs/sim_results.vcd");
|
||||
#endif
|
||||
|
||||
cout << "--------------------------------------------------------------\n";
|
||||
cout << " Starting Simulation, logging to: " << argv[1] << "\n";
|
||||
cout << "--------------------------------------------------------------\n";
|
||||
|
||||
complianceTestsLogPhase = true;
|
||||
performReset(tb, 64);
|
||||
|
||||
// Tick the clock until we are done
|
||||
while(!Verilated::gotFinish()) {
|
||||
tb->clk = 1;
|
||||
tb->eval();
|
||||
tb->clk = 0;
|
||||
tb->eval();
|
||||
|
||||
cycle_cout++;
|
||||
taigaTracer.update_stats(tb);
|
||||
|
||||
if (hasStalled(tb, cout)) break;
|
||||
if (checkForControlNOPs(tb)) break;
|
||||
handleUART(tb, complianceTestsLogPhase, logFile, sigFile);
|
||||
|
||||
#ifdef TRACE_ON
|
||||
verilatorWaveformTracer->dump(vluint32_t(cycle_cout));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef TRACE_ON
|
||||
verilatorWaveformTracer->flush();
|
||||
verilatorWaveformTracer->close();
|
||||
#endif
|
||||
|
||||
cout << "--------------------------------------------------------------\n";
|
||||
cout << " Simulation Completed: " << cycle_cout << " cycles.\n";
|
||||
taigaTracer.print_stats(cout);
|
||||
|
||||
logFile.close();
|
||||
sigFile.close();
|
||||
delete tb;
|
||||
exit(EXIT_SUCCESS);
|
||||
|
||||
|
|
|
@ -6,10 +6,12 @@
|
|||
#include "verilated_vcd_c.h"
|
||||
#include "TaigaTracer.h"
|
||||
|
||||
//#define TRACE_ON
|
||||
using namespace std;
|
||||
int main(int argc, char **argv) {
|
||||
TaigaTracer<Vtaiga_local_mem> *taigaTracer;
|
||||
ofstream logFile, sigFile;
|
||||
ifstream programFile;
|
||||
|
||||
// Initialize Verilators variables
|
||||
Verilated::commandArgs(argc, argv);
|
||||
|
@ -25,12 +27,18 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
if (!argv[3]) {
|
||||
cout << "Missing program file name.\n";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!argv[4]) {
|
||||
cout << "Missing trace log file name.\n";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
logFile.open (argv[1]);
|
||||
sigFile.open (argv[2]);
|
||||
programFile.open (argv[3]);
|
||||
|
||||
if (!logFile.is_open()) {
|
||||
cout << "Failed to open logfile: " << argv[1] << endl;
|
||||
|
@ -40,13 +48,18 @@ int main(int argc, char **argv) {
|
|||
cout << "Failed to open sigFile: " << argv[2] << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!programFile.is_open()) {
|
||||
cout << "Failed to open programFile: " << argv[3] << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Create an instance of our module under test
|
||||
taigaTracer = new TaigaTracer<Vtaiga_local_mem>;
|
||||
taigaTracer = new TaigaTracer<Vtaiga_local_mem>(programFile);
|
||||
taigaTracer->set_log_file(&logFile);
|
||||
#ifdef TRACE_ON
|
||||
taigaTracer->start_tracer(argv[3]);
|
||||
taigaTracer->start_tracer(argv[4]);
|
||||
#endif
|
||||
taigaTracer->reset();
|
||||
cout << "--------------------------------------------------------------\n";
|
||||
cout << " Starting Simulation, logging to: " << argv[1] << "\n";
|
||||
cout << "--------------------------------------------------------------\n";
|
||||
|
@ -70,6 +83,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
logFile.close();
|
||||
sigFile.close();
|
||||
programFile.close();
|
||||
|
||||
delete taigaTracer;
|
||||
|
||||
|
|
|
@ -74,13 +74,26 @@ module taiga_local_mem # (
|
|||
// output logic bus_axi_wvalid,
|
||||
// output logic [5:0]bus_axi_wid,
|
||||
|
||||
//Local Memory
|
||||
output logic [29:0] instruction_bram_addr,
|
||||
output logic instruction_bram_en,
|
||||
output logic [3:0] instruction_bram_be,
|
||||
output logic [31:0] instruction_bram_data_in,
|
||||
input logic [31:0] instruction_bram_data_out,
|
||||
|
||||
output logic [29:0] data_bram_addr,
|
||||
output logic data_bram_en,
|
||||
output logic [3:0] data_bram_be,
|
||||
output logic [31:0] data_bram_data_in,
|
||||
input logic [31:0] data_bram_data_out,
|
||||
|
||||
//Used by verilator
|
||||
output logic write_uart,
|
||||
output logic [7:0] uart_byte,
|
||||
|
||||
//Trace Interface
|
||||
output logic instruction_issued,
|
||||
output logic taiga_events [$bits(taiga_trace_events_t)-1:0],
|
||||
output logic taiga_events [0:$bits(taiga_trace_events_t)-1],
|
||||
output logic [31:0] instruction_pc_dec,
|
||||
output logic [31:0] instruction_data_dec,
|
||||
|
||||
|
@ -213,20 +226,32 @@ module taiga_local_mem # (
|
|||
local_memory_interface data_bram();
|
||||
|
||||
|
||||
byte_en_BRAM #(MEM_LINES, MEMORY_FILE, 1) inst_data_ram (
|
||||
.clk(clk),
|
||||
.addr_a(instruction_bram.addr[$clog2(MEM_LINES)- 1:0]),
|
||||
.en_a(instruction_bram.en),
|
||||
.be_a(instruction_bram.be),
|
||||
.data_in_a(instruction_bram.data_in),
|
||||
.data_out_a(instruction_bram.data_out),
|
||||
assign instruction_bram_addr = instruction_bram.addr;
|
||||
assign instruction_bram_en = instruction_bram.en;
|
||||
assign instruction_bram_be = instruction_bram.be;
|
||||
assign instruction_bram_data_in = instruction_bram.data_in;
|
||||
assign instruction_bram.data_out = instruction_bram_data_out;
|
||||
|
||||
.addr_b(data_bram.addr[$clog2(MEM_LINES)- 1:0]),
|
||||
.en_b(data_bram.en),
|
||||
.be_b(data_bram.be),
|
||||
.data_in_b(data_bram.data_in),
|
||||
.data_out_b(data_bram.data_out)
|
||||
);
|
||||
assign data_bram_addr = data_bram.addr;
|
||||
assign data_bram_en = data_bram.en;
|
||||
assign data_bram_be = data_bram.be;
|
||||
assign data_bram_data_in = data_bram.data_in;
|
||||
assign data_bram.data_out = data_bram_data_out;
|
||||
|
||||
// byte_en_BRAM #(MEM_LINES, MEMORY_FILE, 1) inst_data_ram (
|
||||
// .clk(clk),
|
||||
// .addr_a(instruction_bram.addr[$clog2(MEM_LINES)- 1:0]),
|
||||
// .en_a(instruction_bram.en),
|
||||
// .be_a(instruction_bram.be),
|
||||
// .data_in_a(instruction_bram.data_in),
|
||||
// .data_out_a(instruction_bram.data_out),
|
||||
|
||||
// .addr_b(data_bram.addr[$clog2(MEM_LINES)- 1:0]),
|
||||
// .en_b(data_bram.en),
|
||||
// .be_b(data_bram.be),
|
||||
// .data_in_b(data_bram.data_in),
|
||||
// .data_out_b(data_bram.data_out)
|
||||
// );
|
||||
|
||||
|
||||
taiga cpu(.*, .l2(l2[0]));
|
||||
|
@ -334,8 +359,8 @@ module taiga_local_mem # (
|
|||
logic [$bits(taiga_trace_events_t)-1:0] taiga_events_packed;
|
||||
assign taiga_events_packed = tr.events;
|
||||
always_comb begin
|
||||
foreach (taiga_events_packed[i])
|
||||
taiga_events[i] = taiga_events_packed[i];
|
||||
foreach(taiga_events_packed[i])
|
||||
taiga_events[$bits(taiga_trace_events_t)-1-i] = taiga_events_packed[i];
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -15,14 +15,10 @@ VERILATOR_DIR=$(TAIGA_DIR)/test_benches/verilator
|
|||
TAIGA_SRCS = $(shell cat taiga_compile_order)
|
||||
|
||||
VERILATOR_LINT_IGNORE= -Wno-LITENDIAN -Wno-SYMRSVDWORD
|
||||
VERILATOR_CFLAGS = -CFLAGS "-g0 -Os -march=native -pipe"
|
||||
VERILATOR_CFLAGS = -CFLAGS "-g0 -O3 -march=native -pipe -Wl,-flto" -LDFLAGS "-flto"
|
||||
|
||||
VERILATOR_TRACE_FILE="/data/sim-logs/sim_results.vcd"
|
||||
|
||||
AR="gcc-ar"
|
||||
RANLIB="gcc-ranlib"
|
||||
export AR
|
||||
export RANLIB
|
||||
###############################################################
|
||||
|
||||
#Compiance parameters
|
||||
|
@ -71,13 +67,14 @@ define verilator_local_mem_test
|
|||
mkdir -p $1
|
||||
cp $(VERILATOR_DIR)/TaigaTracer.h $1/
|
||||
cp $(VERILATOR_DIR)/TaigaTracer.cc $1/
|
||||
cp $(VERILATOR_DIR)/SimMem.h $1/
|
||||
cp $(VERILATOR_DIR)/SimMem.cc $1/
|
||||
cp $(VERILATOR_DIR)/taiga_local_mem.cc $1/
|
||||
verilator --cc --exe --Mdir $1 $(VERILATOR_LINT_IGNORE) $(VERILATOR_CFLAGS) $(TAIGA_SRCS) \
|
||||
../test_benches/verilator/taiga_local_mem.sv --top-module taiga_local_mem taiga_local_mem.cc \
|
||||
-GMEMORY_FILE=$2
|
||||
$(MAKE) -C $1 -f Vtaiga_local_mem.mk AR="gcc-ar" RANLIB="gcc-ranlib"
|
||||
../test_benches/verilator/taiga_local_mem.sv --top-module taiga_local_mem taiga_local_mem.cc SimMem.cc
|
||||
$(MAKE) -C $1 -f Vtaiga_local_mem.mk
|
||||
echo $1 > $@
|
||||
./$1/Vtaiga_local_mem $3 $4 $(VERILATOR_TRACE_FILE) >> $@
|
||||
./$1/Vtaiga_local_mem $3 $4 $2 $(VERILATOR_TRACE_FILE) >> $@
|
||||
endef
|
||||
|
||||
.PHONY: lint
|
||||
|
@ -103,8 +100,7 @@ $(embench_hw) : %.hw_init : %
|
|||
|
||||
#Run verilator
|
||||
$(embench_logs) : %_full.log : % $(embench_hw)
|
||||
$(call verilator_local_mem_test,$<,\"$(TAIGA_DIR)/tools/$<.hw_init\","/dev/null","/dev/null")
|
||||
|
||||
$(call verilator_local_mem_test,$<,$(TAIGA_DIR)/tools/$<.hw_init,"/dev/null","/dev/null")
|
||||
run_embench_verilator: $(embench_logs)
|
||||
cat $^ > embench.log
|
||||
|
||||
|
@ -113,7 +109,7 @@ CRUFT= $(EMBENCH_BENCHMARKS) $(embench_hw) $(embench_sim) $(embench_logs) embenc
|
|||
#Called by compliance makefile
|
||||
.PHONY: verilator_taiga_compliance_unit_test
|
||||
verilator_taiga_compliance_unit_test:
|
||||
$(call verilator_local_mem_test,$(COMPLIANCE_BENCHAMRK),\"$(HW_INIT)\", $(LOG_FILE_NAME), $(SIG_FILE_NAME))
|
||||
$(call verilator_local_mem_test,$(COMPLIANCE_BENCHAMRK),$(HW_INIT), $(LOG_FILE_NAME), $(SIG_FILE_NAME))
|
||||
|
||||
.PHONY: verilator_taiga_compliance_tests
|
||||
run_compliance_tests_verilator:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.PHONY: run_dhrystone_verilator
|
||||
run_dhrystone_verilator :
|
||||
$(call verilator_local_mem_test,dhrystone,\"/home/ematthew/Research/RISCV/software/taiga-benchmarks/dhrystone.riscv.hw_init\","/dev/null","/dev/null")
|
||||
$(call verilator_local_mem_test,dhrystone,/home/ematthew/Research/RISCV/software/taiga-benchmarks/dhrystone.riscv.hw_init,"/dev/null","/dev/null")
|
||||
|
||||
.PHONY: build_embench
|
||||
build_embench :
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue