mirror of
https://github.com/MiSTer-devel/MSX1_MiSTer.git
synced 2026-04-26 03:04:41 +00:00
610 lines
17 KiB
C++
610 lines
17 KiB
C++
#include <verilated.h>
|
|
#include "Vemu__Syms.h"
|
|
|
|
#include "imgui.h"
|
|
#include "implot.h"
|
|
#ifndef _MSC_VER
|
|
#include <stdio.h>
|
|
#include <SDL.h>
|
|
#include <SDL_opengl.h>
|
|
#else
|
|
#define WIN32
|
|
#include <dinput.h>
|
|
#endif
|
|
|
|
#include "sim_console.h"
|
|
#include "sim_bus.h"
|
|
#include "sim_video.h"
|
|
#include "sim_audio.h"
|
|
#include "sim_input.h"
|
|
#include "sim_clock.h"
|
|
#include "sim_memory.h"
|
|
#include "sim_sdram.h"
|
|
#include "sim_ddr.h"
|
|
|
|
#include "../imgui/imgui_memory_editor.h"
|
|
#include <verilated_vcd_c.h> //VCD Trace
|
|
#include "../imgui/ImGuiFileDialog.h"
|
|
|
|
#include <iostream>
|
|
#include <fstream>
|
|
using namespace std;
|
|
|
|
// Simulation control
|
|
// ------------------
|
|
int initialReset = 3;
|
|
bool run_enable = 0;
|
|
int batchSize = 150000;
|
|
bool single_step = 0;
|
|
bool multi_step = 0;
|
|
int multi_step_amount = 1024;
|
|
|
|
// Debug GUI
|
|
// ---------
|
|
const char* windowTitle = "Verilator Sim: Arcade-Centipede";
|
|
const char* windowTitle_Control = "Simulation control";
|
|
const char* windowTitle_DebugLog = "Debug log";
|
|
const char* windowTitle_Video = "VGA output";
|
|
const char* windowTitle_Trace = "Trace/VCD control";
|
|
const char* windowTitle_HPS = "HPS control";
|
|
const char* windowTitle_Audio = "Audio output";
|
|
|
|
bool showDebugLog = true;
|
|
DebugConsole console;
|
|
MemoryEditor mem_edit;
|
|
|
|
struct FileDialogData
|
|
{
|
|
uint8_t ioctl_id;
|
|
bool reset;
|
|
uint32_t addr;
|
|
SimDDR* mem;
|
|
};
|
|
|
|
FileDialogData fileData;
|
|
|
|
// HPS emulator
|
|
// ------------
|
|
VL_OUTW(status, 127, 0, 4);
|
|
|
|
const char* slotA1[] = { "ROM","SCC","SCC +","FM - PAC","MegaFlashROM SCC + SD","GameMaster2","FDC","Empty"};
|
|
const char* slotA2[] = { "ROM","SCC","SCC +","FM - PAC","MegaFlashROM SCC + SD","GameMaster2","Empty" };
|
|
const char* slotB[] = { "ROM","SCC","SCC +","FM - PAC","Empty" };
|
|
const char* mapperA[] = { "auto","none","ASCII8","ASCII16","Konami","KonamiSCC","KOEI","linear64","R-TYPE","WIZARDRY" };
|
|
const char* mapperB[] = { "auto","none","ASCII8","ASCII16","Konami","KonamiSCC","KOEI","linear64","R-TYPE","WIZARDRY" };
|
|
const char* sramA[] = { "auto","1kB","2kB","4kB","8kB","16kB","32kB","none" };
|
|
int currentSlotA = 0;
|
|
int currentSlotB = 0;
|
|
int currentMapperA = 0;
|
|
int currentMapperB = 0;
|
|
int currentSramA = 0;
|
|
|
|
|
|
|
|
|
|
//[0] RESET 0
|
|
//[2:1] Aspect ratio 00
|
|
//[4:3] Scanlines 00
|
|
//[6:5] Scale 00
|
|
//[7] Vertical crop 0
|
|
//[8] Tape input 0
|
|
//[9] Tape rewind 0
|
|
//[10] Reset & Detach 0
|
|
//[11] MSX type 0
|
|
//[12] MSX1 VideoMode 0
|
|
//[14:13] MSX2 VideoMode 00
|
|
//[16:15] MSX2 RAM Size 00
|
|
//[19:17] SLOT A CART TYPE 000 currentSlotA & 0x7
|
|
//[23:20] ROM A TYPE MAPPER 0000 currentMapperA & 0xF
|
|
//[25:24] RESERVA 00
|
|
//[28:26] SRAM SIZE 000 currentSramA & 0x7
|
|
//[31:29] SLOT B CART TYPE 000 currentSlotB & 0x7
|
|
//[34:32] ROM B TYPE MAPPER 000 currentMapperB & 0x7
|
|
//[37:35] RESERVA 000
|
|
//[38] BORDER 0
|
|
|
|
|
|
|
|
SimBus bus(console);
|
|
|
|
// Video
|
|
// -----
|
|
#define VGA_WIDTH 256 //320
|
|
#define VGA_HEIGHT 180 //240
|
|
#define VGA_ROTATE 0
|
|
#define VGA_SCALE_X vga_scale
|
|
#define VGA_SCALE_Y vga_scale
|
|
SimVideo video(VGA_WIDTH, VGA_HEIGHT, VGA_ROTATE);
|
|
float vga_scale = 1.5;
|
|
|
|
// Memory
|
|
|
|
#define systemRAM top->emu->systemRAM
|
|
#define VRAMhi top->emu->MSX->vram_hi
|
|
#define VRAMlo top->emu->MSX->vram_lo
|
|
char* systemRAM_mem;
|
|
char* vdp_mem_hi;
|
|
char* vdp_mem_lo;
|
|
|
|
SimSDRAM SDram(console);
|
|
SimDDR DDR(console);
|
|
SimMemory Rams(console);
|
|
|
|
// Verilog module
|
|
// --------------
|
|
Vemu* top = NULL;
|
|
|
|
vluint64_t main_time = 0; // Current simulation time.
|
|
double sc_time_stamp() { // Called by $time in Verilog.
|
|
return main_time;
|
|
}
|
|
|
|
|
|
int clk_sys_freq = 42954545;
|
|
SimClock clk_sys(1); // 42.954545mhz
|
|
SimClock ce_11(3); // 10.75mhz
|
|
|
|
// VCD trace logging
|
|
// -----------------
|
|
VerilatedVcdC* tfp = new VerilatedVcdC; //Trace
|
|
bool Trace = 0;
|
|
char Trace_Deep[3] = "99";
|
|
char Trace_File[30] = "sim.vcd";
|
|
char Trace_Deep_tmp[3] = "99";
|
|
char Trace_File_tmp[30] = "sim.vcd";
|
|
int iTrace_Deep_tmp = 99;
|
|
char SaveModel_File_tmp[20] = "test", SaveModel_File[20] = "test";
|
|
|
|
|
|
|
|
void ChangeStatus(void) {
|
|
status[1] = 0;
|
|
status[0] = 0;
|
|
status[0] |= static_cast<uint64_t>(currentSlotA & 0x7) << 17;
|
|
status[0] |= static_cast<uint64_t>(currentMapperA & 0xF) << 20;
|
|
status[0] |= static_cast<uint64_t>(currentSramA & 0x7) << 26;
|
|
status[0] |= static_cast<uint64_t>(currentSlotB & 0x7) << 29;
|
|
status[0] |= static_cast<uint64_t>(currentMapperB & 0x7) << 32;
|
|
console.AddLog("New Status %X", status);
|
|
}
|
|
|
|
|
|
//Trace Save/Restore
|
|
void save_model(const char* filenamep) {
|
|
/*
|
|
VerilatedSave os;
|
|
os.open(filenamep);
|
|
os << main_time; // user code must save the timestamp, etc
|
|
os << *top;
|
|
*/
|
|
}
|
|
void restore_model(const char* filenamep) {
|
|
/*
|
|
VerilatedRestore os;
|
|
os.open(filenamep);
|
|
os >> main_time;
|
|
os >> *top;
|
|
*/
|
|
}
|
|
|
|
|
|
// Reset simulation variables and clocks
|
|
void resetSim() {
|
|
main_time = 0;
|
|
top->RESET = 1;
|
|
clk_sys.Reset();
|
|
}
|
|
|
|
int verilate() {
|
|
if (!Verilated::gotFinish()) {
|
|
|
|
// Assert reset during startup
|
|
if (main_time < initialReset) {
|
|
top->RESET = 1;
|
|
}
|
|
// Deassert reset after startup
|
|
if (main_time == initialReset) { top->RESET = 0; }
|
|
|
|
// Clock dividers
|
|
clk_sys.Tick();
|
|
|
|
// Set clocks in core
|
|
top->emu->pll->outclk_1 = clk_sys.clk;
|
|
top->emu->hps_io->status = status;
|
|
|
|
// Simulate both edges of fastest clock
|
|
if (clk_sys.clk != clk_sys.old) {
|
|
|
|
// System clock simulates HPS functions
|
|
if (ce_11.clk) {
|
|
// input.BeforeEval();
|
|
}
|
|
|
|
if (clk_sys.IsRising()) {
|
|
if (main_time > initialReset) {
|
|
bus.BeforeEval();
|
|
}
|
|
|
|
SDram.BeforeEval();
|
|
}
|
|
Rams.BeforeEval();
|
|
top->eval();
|
|
|
|
Rams.AfterEval();
|
|
if (clk_sys.IsRising()) {
|
|
SDram.AfterEval();
|
|
DDR.AfterEval();
|
|
|
|
if (top->emu->MSX->vdp_vdp18->ce_pix) {
|
|
uint32_t colour = 0xFF000000 | top->emu->MSX->vdp_vdp18->rgb_b_o << 16 | top->emu->MSX->vdp_vdp18->rgb_g_o << 8 | top->emu->MSX->vdp_vdp18->rgb_r_o;
|
|
video.Clock(top->emu->MSX->vdp_vdp18->hblank_o, top->emu->MSX->vdp_vdp18->vblank_o, top->emu->MSX->vdp_vdp18->hsync_n_o, top->emu->MSX->vdp_vdp18->vsync_n_o, colour);
|
|
}
|
|
}
|
|
|
|
|
|
if (Trace) {
|
|
if (!tfp->isOpen()) tfp->open(Trace_File);
|
|
tfp->dump(main_time); //Trace
|
|
}
|
|
|
|
if (clk_sys.IsFalling()) {
|
|
bus.AfterEval();
|
|
}
|
|
|
|
}
|
|
|
|
// Output pixels on rising edge of pixel clock
|
|
/*
|
|
if (clk_sys.IsRising() && top->ce_pix) {
|
|
uint32_t colour = 0xFF000000 | top->B << 16 | top->G << 8 | top->R;
|
|
video.Clock(top->hblank, top->vblank, top->hsync_n, top->vsync_n, colour);
|
|
}
|
|
*/
|
|
main_time++;
|
|
|
|
return 1;
|
|
}
|
|
|
|
// Stop verilating and cleanup
|
|
top->final();
|
|
delete top;
|
|
exit(0);
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char** argv, char** env) {
|
|
|
|
// Create core and initialise
|
|
top = new Vemu();
|
|
|
|
Verilated::commandArgs(argc, argv);
|
|
|
|
//Prepare for Dump Signals
|
|
Verilated::traceEverOn(true); //Trace
|
|
top->trace(tfp, 1);// atoi(Trace_Deep) ); // Trace 99 levels of hierarchy
|
|
if (Trace) tfp->open(Trace_File);//"simx.vcd"); //Trace
|
|
|
|
#ifdef WIN32
|
|
// Attach debug console to the verilated code
|
|
Verilated::setDebug(console);
|
|
#endif
|
|
|
|
// Attach bus
|
|
systemRAM_mem = Rams.AddRAM(
|
|
&systemRAM->address_a,
|
|
&systemRAM->data_a,
|
|
&systemRAM->q_a,
|
|
&systemRAM->wren_a,
|
|
&systemRAM->address_b,
|
|
&systemRAM->data_b,
|
|
&systemRAM->q_b,
|
|
&systemRAM->wren_b,
|
|
1 << systemRAM->addr_width);
|
|
|
|
vdp_mem_hi = Rams.AddRAM(
|
|
&VRAMhi->address,
|
|
&VRAMhi->data,
|
|
&VRAMhi->q,
|
|
&VRAMhi->wren,
|
|
1 << VRAMhi->addr_width);
|
|
|
|
vdp_mem_lo = Rams.AddRAM(
|
|
&VRAMlo->address,
|
|
&VRAMlo->data,
|
|
&VRAMlo->q,
|
|
&VRAMlo->wren,
|
|
1 << VRAMlo->addr_width);
|
|
|
|
DDR.addr = &top->emu->buffer->addr;
|
|
DDR.dout = &top->emu->buffer->dout;
|
|
DDR.rd = &top->emu->buffer->rd;
|
|
DDR.ready = &top->emu->buffer->ready;
|
|
|
|
SDram.channels_rtl[0].ch_addr = &top->emu->sdram->ch1_addr;
|
|
SDram.channels_rtl[0].ch_din = &top->emu->sdram->ch1_din;
|
|
SDram.channels_rtl[0].ch_dout = &top->emu->sdram->ch1_dout;
|
|
SDram.channels_rtl[0].ch_req = &top->emu->sdram->ch1_req;
|
|
SDram.channels_rtl[0].ch_rnw = &top->emu->sdram->ch1_rnw;
|
|
SDram.channels_rtl[0].ch_ready = &top->emu->sdram->ch1_ready;
|
|
|
|
SDram.channels_rtl[1].ch_addr = &top->emu->sdram->ch2_addr;
|
|
SDram.channels_rtl[1].ch_din = &top->emu->sdram->ch2_din;
|
|
SDram.channels_rtl[1].ch_dout = &top->emu->sdram->ch2_dout;
|
|
SDram.channels_rtl[1].ch_req = &top->emu->sdram->ch2_req;
|
|
SDram.channels_rtl[1].ch_rnw = &top->emu->sdram->ch2_rnw;
|
|
SDram.channels_rtl[1].ch_ready = &top->emu->sdram->ch2_ready;
|
|
|
|
SDram.channels_rtl[2].ch_addr = &top->emu->sdram->ch3_addr;
|
|
SDram.channels_rtl[2].ch_din = &top->emu->sdram->ch3_din;
|
|
SDram.channels_rtl[2].ch_dout = &top->emu->sdram->ch3_dout;
|
|
SDram.channels_rtl[2].ch_req = &top->emu->sdram->ch3_req;
|
|
SDram.channels_rtl[2].ch_rnw = &top->emu->sdram->ch3_rnw;
|
|
SDram.channels_rtl[2].ch_ready = &top->emu->sdram->ch3_ready;
|
|
SDram.channels_rtl[2].ch_done = &top->emu->sdram->ch3_done;
|
|
SDram.Initialise(0x1000000);
|
|
|
|
DDR.Initialise(256*1024*1024); //256Mb
|
|
|
|
bus.ioctl_addr = &top->emu->hps_io->ioctl_addr;
|
|
bus.ioctl_index = &top->emu->hps_io->ioctl_index;
|
|
bus.ioctl_wait = &top->emu->hps_io->ioctl_wait;
|
|
bus.ioctl_download = &top->emu->hps_io->ioctl_download;
|
|
bus.ioctl_wr = &top->emu->hps_io->ioctl_wr;
|
|
bus.ioctl_dout = &top->emu->hps_io->ioctl_dout;
|
|
top->emu->hps_io->sdram_sz = SDram.getHPSsize();
|
|
|
|
// Setup video output
|
|
if (video.Initialise(windowTitle) == 1) { return 1; }
|
|
|
|
|
|
//30000000 ROM Pack = Romky MSX 3 MB
|
|
//30300000 FW Pack = Romky Cartrige 9 MB
|
|
//30C00000 ROM CART 1 5 MB
|
|
//31100000 ROM CART 2 5 MB
|
|
//31600000 ROM CRC 1 MB
|
|
//31700000 CAS
|
|
//40000000 Maximum
|
|
|
|
//bus.QueueDownload("./rom/Deep Dungeon 1 - Scaptrust [ASCII8SRAM2] .rom", 3, true, 0x30C00000, &DDR); //27FD8F9A
|
|
bus.QueueDownload("./rom/Mappers/output_data.bin", 6, true, 0x31600000, &DDR);
|
|
bus.QueueDownload("./rom/ROMpack/Philips_VG_8020-00.MSX", 1, true, 0x30000000, &DDR);
|
|
bus.QueueDownload("./rom/roms/10th Frame - Access Software [ASCII16] .rom", 3, true, 0x30C00000, &DDR);
|
|
|
|
//bus.QueueDownload("./rom/Philips_NMS_8245.msx", 1, true);
|
|
//bus.QueueDownload("./rom/Philips_NMS_8245.msx", 1, false);
|
|
|
|
|
|
#ifdef WIN32
|
|
MSG msg;
|
|
ZeroMemory(&msg, sizeof(msg));
|
|
while (msg.message != WM_QUIT)
|
|
{
|
|
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
continue;
|
|
}
|
|
#else
|
|
bool done = false;
|
|
while (!done)
|
|
{
|
|
SDL_Event event;
|
|
while (SDL_PollEvent(&event))
|
|
{
|
|
ImGui_ImplSDL2_ProcessEvent(&event);
|
|
if (event.type == SDL_QUIT)
|
|
done = true;
|
|
}
|
|
#endif
|
|
video.StartFrame();
|
|
|
|
// Draw GUI
|
|
// --------
|
|
ImGui::NewFrame();
|
|
|
|
// Simulation control window
|
|
ImGui::Begin(windowTitle_Control);
|
|
ImGui::SetWindowPos(windowTitle_Control, ImVec2(0, 0), ImGuiCond_Once);
|
|
ImGui::SetWindowSize(windowTitle_Control, ImVec2(500, 150), ImGuiCond_Once);
|
|
if (ImGui::Button("Reset simulation")) { resetSim(); } ImGui::SameLine();
|
|
if (ImGui::Button("Start running")) { run_enable = 1; } ImGui::SameLine();
|
|
if (ImGui::Button("Stop running")) { run_enable = 0; } ImGui::SameLine();
|
|
ImGui::Checkbox("RUN", &run_enable);
|
|
//ImGui::PopItemWidth();
|
|
ImGui::SliderInt("Run batch size", &batchSize, 1, 250000);
|
|
if (single_step == 1) { single_step = 0; }
|
|
if (ImGui::Button("Single Step")) { run_enable = 0; single_step = 1; }
|
|
ImGui::SameLine();
|
|
if (multi_step == 1) { multi_step = 0; }
|
|
if (ImGui::Button("Multi Step")) { run_enable = 0; multi_step = 1; }
|
|
//ImGui::SameLine();
|
|
ImGui::SliderInt("Multi step amount", &multi_step_amount, 8, 1024);
|
|
|
|
ImGui::End();
|
|
|
|
|
|
// Debug log window
|
|
console.Draw(windowTitle_DebugLog, &showDebugLog, ImVec2(500, 700));
|
|
ImGui::SetWindowPos(windowTitle_DebugLog, ImVec2(0, 160), ImGuiCond_Once);
|
|
/*
|
|
// Memory debug
|
|
ImGui::Begin("DDRAM");
|
|
mem_edit.DrawContents(DDR.GetMem(), 256*1024*1024, 0x30000000);
|
|
ImGui::End();
|
|
|
|
ImGui::Begin("SDRAM");
|
|
mem_edit.DrawContents(SDram.GetMem(), 0x1000000, 0);
|
|
ImGui::End();
|
|
|
|
|
|
ImGui::Begin("VRAM Editor HI");
|
|
mem_edit.DrawContents(vdp_mem_hi, 1 << VRAMhi->addr_width, 0);
|
|
ImGui::End();
|
|
|
|
ImGui::Begin("VRAM Editor LO");
|
|
mem_edit.DrawContents(vdp_mem_lo, 1 << VRAMlo->addr_width, 0);
|
|
ImGui::End();
|
|
|
|
|
|
ImGui::Begin("RAM Editor");
|
|
mem_edit.DrawContents(systemRAM_mem, 1 << systemRAM->addr_width, 0);
|
|
ImGui::End();
|
|
|
|
*/
|
|
//HPS emulace
|
|
ImGui::Begin(windowTitle_HPS);
|
|
ImGui::SetWindowPos(windowTitle_Trace, ImVec2(0, 870), ImGuiCond_Once);
|
|
ImGui::SetWindowSize(windowTitle_Trace, ImVec2(500, 150), ImGuiCond_Once);
|
|
|
|
|
|
|
|
if (ImGui::Button("Load ROM PACK")) {
|
|
fileData.addr = 0x30000000;
|
|
fileData.ioctl_id = 1;
|
|
fileData.mem = &DDR;
|
|
fileData.reset = true;
|
|
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "ROM PACK LOAD", ".msx", "./rom/ROMpack/", 1, &fileData);
|
|
}
|
|
if (ImGui::Button("Load FW PACK")) {
|
|
fileData.addr = 0x30300000;
|
|
fileData.ioctl_id = 2;
|
|
fileData.mem = &DDR;
|
|
fileData.reset = true;
|
|
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "FW PACK LOAD", ".msx", "./rom/FWpack/", 1, &fileData);
|
|
}
|
|
|
|
if (ImGui::Button("Load DB MAPPER")) {
|
|
fileData.addr = 0x31600000;
|
|
fileData.ioctl_id = 6;
|
|
fileData.mem = &DDR;
|
|
fileData.reset = true;
|
|
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "DB MAPPERS LOAD", ".db", "./rom/Mappers/", 1, &fileData);
|
|
}
|
|
|
|
if (ImGui::Button("Load ROM A")) {
|
|
fileData.addr = 0x30C00000;
|
|
fileData.ioctl_id = 3;
|
|
fileData.mem = &DDR;
|
|
fileData.reset = true;
|
|
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "ROM A", ".rom", "./rom/roms/", 1, &fileData);
|
|
}
|
|
|
|
if (ImGui::Button("Load ROM B")) {
|
|
fileData.addr = 0x31100000;
|
|
fileData.ioctl_id = 4;
|
|
fileData.mem = &DDR;
|
|
fileData.reset = true;
|
|
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "ROM B", ".rom", "./rom/roms/", 1, &fileData);
|
|
}
|
|
|
|
ImGui::PushItemWidth(180.0f);
|
|
if (ImGui::Combo("SLOT A", ¤tSlotA, slotA1, IM_ARRAYSIZE(slotA1)))
|
|
{
|
|
ChangeStatus();
|
|
}
|
|
if (ImGui::Combo("MAPPER A", ¤tMapperA, mapperA, IM_ARRAYSIZE(mapperA)))
|
|
{
|
|
ChangeStatus();
|
|
}
|
|
if (ImGui::Combo("SRAM A", ¤tSramA, sramA, IM_ARRAYSIZE(sramA)))
|
|
{
|
|
ChangeStatus();
|
|
}
|
|
if (ImGui::Combo("SLOT B", ¤tSlotB, slotB, IM_ARRAYSIZE(slotB)))
|
|
{
|
|
ChangeStatus();
|
|
}
|
|
if (ImGui::Combo("MAPPER B", ¤tMapperB, mapperB, IM_ARRAYSIZE(mapperB)))
|
|
{
|
|
ChangeStatus();
|
|
}
|
|
ImGui::PopItemWidth();
|
|
if (ImGuiFileDialog::Instance()->Display("ChooseFileDlgKey")) {
|
|
if (ImGuiFileDialog::Instance()->IsOk()) {
|
|
std::string filePath = ImGuiFileDialog::Instance()->GetFilePathName();
|
|
std::string fileName = ImGuiFileDialog::Instance()->GetCurrentFileName();
|
|
FileDialogData *data = static_cast<FileDialogData*>(ImGuiFileDialog::Instance()->GetUserDatas());
|
|
bus.QueueDownload(ImGuiFileDialog::Instance()->GetFilePathName(), data->ioctl_id, data->reset, data->addr, data->mem);
|
|
}
|
|
ImGuiFileDialog::Instance()->Close();
|
|
}
|
|
ImGui::End();
|
|
|
|
|
|
// Trace/VCD window
|
|
ImGui::Begin(windowTitle_Trace);
|
|
ImGui::SetWindowPos(windowTitle_Trace, ImVec2(0, 870), ImGuiCond_Once);
|
|
ImGui::SetWindowSize(windowTitle_Trace, ImVec2(500, 150), ImGuiCond_Once);
|
|
|
|
if (ImGui::Button("Start VCD Export")) { Trace = 1; } ImGui::SameLine();
|
|
if (ImGui::Button("Stop VCD Export")) { Trace = 0; } ImGui::SameLine();
|
|
if (ImGui::Button("Flush VCD Export")) { tfp->flush(); } ImGui::SameLine();
|
|
ImGui::Checkbox("Export VCD", &Trace);
|
|
|
|
ImGui::PushItemWidth(120);
|
|
if (ImGui::InputInt("Deep Level", &iTrace_Deep_tmp, 1, 100, ImGuiInputTextFlags_EnterReturnsTrue))
|
|
{
|
|
top->trace(tfp, iTrace_Deep_tmp);
|
|
}
|
|
|
|
if (ImGui::InputText("TraceFilename", Trace_File_tmp, IM_ARRAYSIZE(Trace_File), ImGuiInputTextFlags_EnterReturnsTrue))
|
|
{
|
|
strcpy(Trace_File, Trace_File_tmp); //TODO onChange Close and open new trace file
|
|
tfp->close();
|
|
if (Trace) tfp->open(Trace_File);
|
|
};
|
|
ImGui::Separator();
|
|
if (ImGui::Button("Save Model")) { save_model(SaveModel_File); } ImGui::SameLine();
|
|
if (ImGui::Button("Load Model")) {
|
|
restore_model(SaveModel_File);
|
|
} ImGui::SameLine();
|
|
if (ImGui::InputText("SaveFilename", SaveModel_File_tmp, IM_ARRAYSIZE(SaveModel_File), ImGuiInputTextFlags_EnterReturnsTrue))
|
|
{
|
|
strcpy(SaveModel_File, SaveModel_File_tmp); //TODO onChange Close and open new trace file
|
|
}
|
|
ImGui::End();
|
|
int windowX = 550;
|
|
int windowWidth = (VGA_WIDTH * VGA_SCALE_X) + 24;
|
|
int windowHeight = (VGA_HEIGHT * VGA_SCALE_Y) + 90;
|
|
|
|
// Video window
|
|
ImGui::Begin(windowTitle_Video);
|
|
ImGui::SetWindowPos(windowTitle_Video, ImVec2(windowX, 0), ImGuiCond_Once);
|
|
ImGui::SetWindowSize(windowTitle_Video, ImVec2(windowWidth, windowHeight), ImGuiCond_Once);
|
|
|
|
ImGui::SetNextItemWidth(400);
|
|
ImGui::SliderFloat("Zoom", &vga_scale, 1, 8); ImGui::SameLine();
|
|
ImGui::SetNextItemWidth(200);
|
|
ImGui::SliderInt("Rotate", &video.output_rotate, -1, 1); ImGui::SameLine();
|
|
ImGui::Checkbox("Flip V", &video.output_vflip);
|
|
ImGui::Text("main_time: %d frame_count: %d sim FPS: %f", main_time, video.count_frame, video.stats_fps);
|
|
//ImGui::Text("pixel: %06d line: %03d", video.count_pixel, video.count_line);
|
|
|
|
// Draw VGA output
|
|
ImGui::Image(video.texture_id, ImVec2(video.output_width * VGA_SCALE_X, video.output_height * VGA_SCALE_Y));
|
|
ImGui::End();
|
|
|
|
|
|
video.UpdateTexture();
|
|
|
|
// Run simulation
|
|
if (run_enable) {
|
|
for (int step = 0; step < batchSize; step++) { verilate(); }
|
|
}
|
|
else {
|
|
if (single_step) { verilate(); }
|
|
if (multi_step) {
|
|
for (int step = 0; step < multi_step_amount; step++) { verilate(); }
|
|
}
|
|
}
|
|
}
|
|
|
|
// Clean up before exit
|
|
// --------------------
|
|
|
|
video.CleanUp();
|
|
|
|
return 0;
|
|
}
|