1
0
mirror of https://github.com/mist-devel/mist-board.git synced 2026-02-07 16:31:17 +00:00
Files
mist-devel.mist-board/cores/bbc/bench/vidproc/vidproc.cpp
2015-09-29 21:05:29 +02:00

264 lines
6.2 KiB
C++

#include <verilated.h> // Defines common routines
#include "Vvidproc.h"
#include "verilated_vcd_c.h"
#include "edge.h"
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <stdexcept>
#include <SDL/SDL.h>
Vvidproc *uut; // Instantiation of module
vluint64_t main_time = 0; // Current simulation time
// This is a 64-bit integer to reduce wrap over issues and
// allow modulus. You can also use a double, if you wish.
double sc_time_stamp () { // Called by $time in Verilog
return main_time; // converts to double, to match
// what SystemC does
}
int loadDataFile(std::string fileName, int* data, int size)
{
int i = 0;
std::ifstream input(fileName.c_str());
std::string line;
while(std::getline(input, line))
{
unsigned int x;
std::stringstream ss;
ss << std::hex << line;
ss >> x;
if (i < size)
{
data[i++] = x;
}
else
{
throw std::runtime_error("bounds of array exceeded.");
}
}
return i;
}
void setPalette()
{
uut->v__DOT__palette[0] = 0x7;
uut->v__DOT__palette[1] = 0x1;
uut->v__DOT__palette[2] = 0x2;
uut->v__DOT__palette[3] = 0x3;
uut->v__DOT__palette[4] = 0x4;
uut->v__DOT__palette[5] = 0x5;
uut->v__DOT__palette[6] = 0x6;
uut->v__DOT__palette[7] = 0x7;
uut->v__DOT__palette[8] = 0x8;
uut->v__DOT__palette[9] = 0x9;
uut->v__DOT__palette[10] = 0xA;
uut->v__DOT__palette[11] = 0xB;
uut->v__DOT__palette[12] = 0xC;
uut->v__DOT__palette[13] = 0xD;
uut->v__DOT__palette[14] = 0xE;
uut->v__DOT__palette[15] = 0xF;
}
void printVideoRegister()
{
//reg [15:0] vidc_cr; // control register.
//std::cout << std::hex << "vidc_cr = 0x" << uut->v__DOT__vidc_cr << std::dec << ";" << std::endl;
//reg [12:0] vidc_palette[0:15]; // palette register.
for (int i=0; i<16; i++)
{
std::cout << "palette[" << i << "] = 0x" << std::hex << (int)uut->v__DOT__palette[i] << std::dec << ";" << std::endl;
}
}
bool isCursor(int x, int y)
{
return (x > 32) && (x < 64) && (y > 30) && (y < 38);
}
bool isEnabled(int x, int y)
{
int xstart = 50;
int ystart = 50;
return (x >= xstart) && (x < xstart+320) && (y >= ystart) && (y < ystart+256);
}
int main(int argc, char** argv)
{
// SDL events
SDL_Event event;
srand(12345);
int mem_delay = 4;
int screen_data[38404*2];
int screen_idx = 0;
bool vcdTrace = true;
VerilatedVcdC* tfp = NULL;
//The images
SDL_Surface* screen = NULL;
SDL_Init(SDL_INIT_VIDEO);
//Set up screen
screen = SDL_SetVideoMode( 800, 524, 32, SDL_SWSURFACE | SDL_RESIZABLE );
//Update Screen
SDL_Flip( screen );
// Check that the window was successfully made
if (screen == NULL)
{
// In the event that the window could not be made...
printf("Could not create window: %s\n", SDL_GetError());
return 1;
}
// simulate a monitor
int xcount = 0;
int ycount = 0;
Edge clock;
Edge clken;
std::string fileName = "vidproc.dat";
if (argc > 1)
{
fileName = std::string(argv[1]);
}
Verilated::commandArgs(argc, argv); // Remember args
uut = new Vvidproc; // Create instance
uut->eval();
uut->eval();
//loadDataFile(fileName, (int *)screen_data, sizeof(screen_data));
if (vcdTrace)
{
Verilated::traceEverOn(true);
tfp = new VerilatedVcdC;
uut->trace(tfp, 99);
std::string vcdname = "vidproc.vcd";
tfp->open(vcdname.c_str());
}
uut->nRESET = 0;
uut->eval();
setPalette();
uut->eval();
Uint8 *p = (Uint8 *)screen->pixels;
while (!Verilated::gotFinish())
{
if (main_time > 32)
{
uut->nRESET = 1; // Deassert reset
setPalette();
}
if (main_time >= 2)
{
uut->CLOCK = uut->CLOCK ? 0 : 1; // Toggle clock
}
uut->CLKEN = ((main_time % 8) < 2) ? 1 : 0;
uut->DISEN = isEnabled(xcount, ycount) ? 1 : 0;
uut->eval(); // Evaluate model
if (tfp != NULL)
{
tfp->dump (main_time);
}
clock.Update(uut->CLOCK);
clken.Update(uut->CLKEN);
if (clock.PosEdge())
{
uut->DI_RAM = 0x1;
}
if (ycount >= 480)
{
SDL_Flip( screen );
p = (Uint8 *)screen->pixels;
// print out the number of lines processed.
std::cerr << ycount << std::endl;
ycount = 0;
xcount = 0;
screen_idx = 0;
}
else if (xcount >= 640)
{
while( SDL_PollEvent( &event ) )
{
/* We are only worried about SDL_KEYDOWN and SDL_KEYUP events */
switch( event.type )
{
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_v)
{
printVideoRegister();
}
break;
default:
break;
}
}
ycount++;
xcount = 0;
p = (Uint8 *)screen->pixels;
p+= ycount * screen->w *4;
}
else if (clken.PosEdge()) // && (bool)uut->vsync && (bool) uut->hsync)
{
uut->CURSOR = isCursor(xcount, ycount);
if ((ycount < screen->h) && (xcount <= screen->w))
{
*p++ = ((unsigned char)uut->R) ? 0xFFFF : 0; //<< 4 | (unsigned char)uut->video_b;
*p++ = ((unsigned char)uut->G) ? 0xFFFF : 0; //<< 4 | (unsigned char)uut->video_g;
*p++ = ((unsigned char)uut->B) ? 0xFFFF : 0; //<< 4 | (unsigned char)uut->video_r;
p++;
xcount++;
}
}
main_time++; // Time passes...
}
uut->final(); // Done simulating
if (tfp != NULL)
{
tfp->close();
delete tfp;
}
//Quit SDL
SDL_Quit();
delete uut;
}