RASCSI/cpp/scsimon/sm_vcd_report.cpp

148 lines
6.0 KiB
C++
Raw Normal View History

//---------------------------------------------------------------------------
//
// SCSI Target Emulator PiSCSI
// for Raspberry Pi
//
// Copyright (C) 2020-2021 akuker
//
// [ SCSI Bus Monitor ]
//
//---------------------------------------------------------------------------
#include "hal/data_sample.h"
#include "hal/gpiobus.h"
#include "hal/log.h"
#include "sm_core.h"
#include "sm_reports.h"
#include <fstream>
#include <iostream>
#include <sstream>
using namespace std;
//---------------------------------------------------------------------------
//
// Constant declarations
//
//---------------------------------------------------------------------------
// Symbol definition for the VCD file
// These are just arbitrary symbols. They can be anything allowed by the VCD file format,
// as long as they're consistently used.
const char SYMBOL_PIN_DAT = '#';
const char SYMBOL_PIN_ATN = '+';
const char SYMBOL_PIN_RST = '$';
const char SYMBOL_PIN_ACK = '%';
const char SYMBOL_PIN_REQ = '^';
const char SYMBOL_PIN_MSG = '&';
const char SYMBOL_PIN_CD = '*';
const char SYMBOL_PIN_IO = '(';
const char SYMBOL_PIN_BSY = ')';
const char SYMBOL_PIN_SEL = '-';
Fix simple SonarCloud issues (#834) * Fixing SonarCloud issues, first round * Fixing SonarCLoud issues, next round * Fixing SonarQube issues, next round * Fixed warning * Replaced empty constructors/destructors with = default; * Fixed warning * Replaced new * Use constants instead of macros * Use structured binding declarations * Use init statements for if * Use string views * Use enum class, use using instead of typedef * Fixed more SonarCloud warnings * Replaced redundant/duplicate types with auto * Devlared methods const * Memory management update * Fixed warning * Added missing const * Improved RaScsiResponse memory management * Improved memory management * Improved memory management * Replaced macros by constants, removed unused constants * Made member private * Fixed warning * Added comment * Fixed shadowing warnings * Cleanup * Cleanup * Cleanup * Fixed shadowing warning * Removed unused code * Fixed more warnings * Removed obsolete casts * Fixed warnings * Removed unused field * Removed library not needed by rasctl * Include cleanup * Updated platform check for better compatibility * Improved check for invalid option. This prevents rasctl to break on macos. * Updated option check * Fixed typo * Added TODO * Removed macro * Scope update * Replaced macro * Added TODO, update memory management * Fixed typo * Replaced NULL by nullptr * Use more structured bindings * Added TODO * Use calloc instead of mallco to not need memset * Fixed warnings * Fixed SonarQube initialization issues * Fixed warning * Cleaned up override/virtual/final * Fixed warnings * Constructor update * Fixed tests * Improved memory management * Added missing const * Added const * Fixed two bugs reported by SonarCloud * Fix SonarCloud hotspot * Fixed memory management * Memory management update * Addressing hotspot by using strncpy * Fixed SonarCloud issues * Fixed SonarQube issues * Added missing const * Added const * Added const * Suppress false positive * Added SonarQube suppressions for false positives * Added suppresoin * Fixed code smells * Reverted changes that is a SonarQube issue, but caused problems with -O3 * Removed TODO based on review
2022-09-07 14:38:42 +00:00
const char SYMBOL_PIN_PHASE = '=';
// We'll use position 0 in the prev_value array to store the previous phase
Fix simple SonarCloud issues (#834) * Fixing SonarCloud issues, first round * Fixing SonarCLoud issues, next round * Fixing SonarQube issues, next round * Fixed warning * Replaced empty constructors/destructors with = default; * Fixed warning * Replaced new * Use constants instead of macros * Use structured binding declarations * Use init statements for if * Use string views * Use enum class, use using instead of typedef * Fixed more SonarCloud warnings * Replaced redundant/duplicate types with auto * Devlared methods const * Memory management update * Fixed warning * Added missing const * Improved RaScsiResponse memory management * Improved memory management * Improved memory management * Replaced macros by constants, removed unused constants * Made member private * Fixed warning * Added comment * Fixed shadowing warnings * Cleanup * Cleanup * Cleanup * Fixed shadowing warning * Removed unused code * Fixed more warnings * Removed obsolete casts * Fixed warnings * Removed unused field * Removed library not needed by rasctl * Include cleanup * Updated platform check for better compatibility * Improved check for invalid option. This prevents rasctl to break on macos. * Updated option check * Fixed typo * Added TODO * Removed macro * Scope update * Replaced macro * Added TODO, update memory management * Fixed typo * Replaced NULL by nullptr * Use more structured bindings * Added TODO * Use calloc instead of mallco to not need memset * Fixed warnings * Fixed SonarQube initialization issues * Fixed warning * Cleaned up override/virtual/final * Fixed warnings * Constructor update * Fixed tests * Improved memory management * Added missing const * Added const * Fixed two bugs reported by SonarCloud * Fix SonarCloud hotspot * Fixed memory management * Memory management update * Addressing hotspot by using strncpy * Fixed SonarCloud issues * Fixed SonarQube issues * Added missing const * Added const * Added const * Suppress false positive * Added SonarQube suppressions for false positives * Added suppresoin * Fixed code smells * Reverted changes that is a SonarQube issue, but caused problems with -O3 * Removed TODO based on review
2022-09-07 14:38:42 +00:00
const int PIN_PHASE = 0;
//---------------------------------------------------------------------------
//
// Variable declarations
//
//---------------------------------------------------------------------------
static array<uint8_t,32> prev_value = {0xFF};
static void vcd_output_if_changed_phase(ofstream &fp, phase_t data, int pin, char symbol)
{
if (prev_value[pin] != static_cast<uint8_t>(data)) {
prev_value[pin] = static_cast<uint8_t>(data);
fp << "s" << BUS::GetPhaseStrRaw(data) << " " << symbol << endl;
}
}
static void vcd_output_if_changed_bool(ofstream &fp, bool data, int pin, char symbol)
{
if (prev_value[pin] != data) {
prev_value[pin] = data;
fp << data << symbol << endl;
}
}
static void vcd_output_if_changed_byte(ofstream &fp, uint8_t data, int pin, char symbol)
{
if (prev_value[pin] != data) {
prev_value[pin] = data;
fp << "b" << fmt::format("{0:8b}", data) << " " << symbol << endl;
}
}
void scsimon_generate_value_change_dump(const string &filename, const vector<shared_ptr<DataSample>> &data_capture_array)
{
spdlog::trace("Creating Value Change Dump file (" + filename + ")");
ofstream vcd_ofstream;
vcd_ofstream.open(filename.c_str(), ios::out);
// Get the current time
time_t rawtime;
time(&rawtime);
struct tm timeinfo;
localtime_r(&rawtime, &timeinfo);
string timestamp;
timestamp.resize(256);
strftime(&timestamp[0], timestamp.size(), "%d-%m-%Y %H-%M-%S", &timeinfo);
vcd_ofstream << "$date" << endl
<< timestamp << endl
<< "$end" << endl
<< "$version" << endl
<< " VCD generator tool version info text." << endl
<< "$end" << endl
<< "$comment" << endl
<< " Tool build date:" << __TIMESTAMP__ << endl
<< "$end" << endl
<< "$timescale 1 ns $end" << endl
<< "$scope module logic $end" << endl
<< "$var wire 1 " << SYMBOL_PIN_BSY << " BSY $end" << endl
<< "$var wire 1 " << SYMBOL_PIN_SEL << " SEL $end" << endl
<< "$var wire 1 " << SYMBOL_PIN_CD << " CD $end" << endl
<< "$var wire 1 " << SYMBOL_PIN_IO << " IO $end" << endl
<< "$var wire 1 " << SYMBOL_PIN_MSG << " MSG $end" << endl
<< "$var wire 1 " << SYMBOL_PIN_REQ << " REQ $end" << endl
<< "$var wire 1 " << SYMBOL_PIN_ACK << " ACK $end" << endl
<< "$var wire 1 " << SYMBOL_PIN_ATN << " ATN $end" << endl
<< "$var wire 1 " << SYMBOL_PIN_RST << " RST $end" << endl
<< "$var wire 8 " << SYMBOL_PIN_DAT << " data $end" << endl
<< "$var string 1 " << SYMBOL_PIN_PHASE << " phase $end" << endl
<< "$upscope $end" << endl
<< "$enddefinitions $end" << endl;
// Initial values - default to zeros
vcd_ofstream << "$dumpvars" << endl
<< "0" << SYMBOL_PIN_BSY << endl
<< "0" << SYMBOL_PIN_SEL << endl
<< "0" << SYMBOL_PIN_CD << endl
<< "0" << SYMBOL_PIN_IO << endl
<< "0" << SYMBOL_PIN_MSG << endl
<< "0" << SYMBOL_PIN_REQ << endl
<< "0" << SYMBOL_PIN_ACK << endl
<< "0" << SYMBOL_PIN_ATN << endl
<< "0" << SYMBOL_PIN_RST << endl
<< "b00000000 " << SYMBOL_PIN_DAT << endl
<< "$end" << endl;
for (shared_ptr<DataSample> cur_sample : data_capture_array) {
vcd_ofstream << "#" << (double)cur_sample->GetTimestamp() * ScsiMon::ns_per_loop << endl;
vcd_output_if_changed_bool(vcd_ofstream, cur_sample->GetBSY(), PIN_BSY, SYMBOL_PIN_BSY);
vcd_output_if_changed_bool(vcd_ofstream, cur_sample->GetSEL(), PIN_SEL, SYMBOL_PIN_SEL);
vcd_output_if_changed_bool(vcd_ofstream, cur_sample->GetCD(), PIN_CD, SYMBOL_PIN_CD);
vcd_output_if_changed_bool(vcd_ofstream, cur_sample->GetIO(), PIN_IO, SYMBOL_PIN_IO);
vcd_output_if_changed_bool(vcd_ofstream, cur_sample->GetMSG(), PIN_MSG, SYMBOL_PIN_MSG);
vcd_output_if_changed_bool(vcd_ofstream, cur_sample->GetREQ(), PIN_REQ, SYMBOL_PIN_REQ);
vcd_output_if_changed_bool(vcd_ofstream, cur_sample->GetACK(), PIN_ACK, SYMBOL_PIN_ACK);
vcd_output_if_changed_bool(vcd_ofstream, cur_sample->GetATN(), PIN_ATN, SYMBOL_PIN_ATN);
vcd_output_if_changed_bool(vcd_ofstream, cur_sample->GetRST(), PIN_RST, SYMBOL_PIN_RST);
vcd_output_if_changed_byte(vcd_ofstream, cur_sample->GetDAT(), PIN_DT0, SYMBOL_PIN_DAT);
vcd_output_if_changed_phase(vcd_ofstream, cur_sample->GetPhase(), PIN_PHASE, SYMBOL_PIN_PHASE);
}
vcd_ofstream.close();
}