Merge branch 'vga' of github.com:NJU-ProjectN/nvboard into vga
This commit is contained in:
commit
9799b40fb9
|
@ -11,10 +11,15 @@ enum {
|
|||
};
|
||||
|
||||
// component type
|
||||
enum{
|
||||
enum {
|
||||
BUTTON_TYPE = 1, SWICTH_TYPE, NAIVE_LED_TYPE, RGB_LED_TYPE, SEGS7_TYPE, VGA_TYPE
|
||||
};
|
||||
|
||||
// logic type
|
||||
enum {
|
||||
COMB_TYPE = 1, SEQ_TYPE = 2
|
||||
};
|
||||
|
||||
union Pin{
|
||||
input_pin m_in;
|
||||
output_pin m_out;
|
||||
|
@ -48,7 +53,7 @@ public:
|
|||
void set_state(int val);
|
||||
void add_input(const input_pin &in);
|
||||
void add_output(const output_pin &out);
|
||||
virtual void update_gui(int newval);
|
||||
virtual void update_gui();
|
||||
virtual void update_state();
|
||||
|
||||
friend void delete_components();
|
||||
|
@ -57,14 +62,14 @@ public:
|
|||
class RGB_LED : public Component{
|
||||
public:
|
||||
RGB_LED(SDL_Renderer *rend, int cnt, int init_val, int it, int ct);
|
||||
virtual void update_gui(int newval);
|
||||
virtual void update_gui();
|
||||
virtual void update_state();
|
||||
};
|
||||
|
||||
class SEGS7 : public Component{
|
||||
public:
|
||||
SEGS7(SDL_Renderer *rend, int cnt, int init_val, int it, int ct);
|
||||
virtual void update_gui(int newval);
|
||||
virtual void update_gui();
|
||||
virtual void update_state();
|
||||
};
|
||||
|
||||
|
|
|
@ -24,8 +24,14 @@
|
|||
|
||||
#define CLK_FREQ 1000000
|
||||
|
||||
#define CLK_DBG
|
||||
|
||||
#define VGA_ENA
|
||||
|
||||
// III. Experimental Function
|
||||
|
||||
#define HARDWARE_ACC
|
||||
//#define HARDWARE_ACC
|
||||
|
||||
//#define VSYNC
|
||||
|
||||
#endif
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef _VFPGA_VGA_H
|
||||
#define _VFPGA_VGA_H
|
||||
|
||||
#include <component.h>
|
||||
#include <constrs.h>
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
|
@ -16,20 +17,19 @@ struct VGA_MODE{
|
|||
int v_frontporch, v_active, v_backporch, v_total;
|
||||
};
|
||||
|
||||
class VGA{
|
||||
SDL_Window *vga_window;
|
||||
SDL_Renderer *vga_renderer;
|
||||
SDL_Texture *vga_texture;
|
||||
class VGA : public Component{
|
||||
private:
|
||||
int vga_screen_width, vga_screen_height;
|
||||
uint32_t *pixels;
|
||||
int vga_pos;
|
||||
int vga_pre_clk, vga_pre_vsync, vga_pre_hsync;
|
||||
int vga_vaddr, vga_haddr;
|
||||
void update_screen();
|
||||
public:
|
||||
VGA();
|
||||
VGA(SDL_Renderer *rend, int cnt, int init_val, int it, int ct);
|
||||
~VGA();
|
||||
void update_vga();
|
||||
|
||||
virtual void update_gui();
|
||||
virtual void update_state();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -13,7 +13,12 @@ static uint64_t freq;
|
|||
static uint64_t init_time;
|
||||
static uint64_t clk_cnt;
|
||||
|
||||
// Return true at posedge or negedge of clk.
|
||||
bool read_clock() {
|
||||
#ifdef CLK_DBG
|
||||
input_map[input_pin::CLK] ^= 1;
|
||||
return true;
|
||||
#else
|
||||
if (!clock_ena) {
|
||||
freq = SDL_GetPerformanceFrequency();
|
||||
init_time = SDL_GetPerformanceCounter();
|
||||
|
@ -28,4 +33,5 @@ bool read_clock() {
|
|||
return true;
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
|
@ -1,11 +1,9 @@
|
|||
#include <component.h>
|
||||
#include <configs.h>
|
||||
#include <render.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include <nboard.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_image.h>
|
||||
|
||||
std::vector<Component *> components;
|
||||
|
||||
|
@ -84,7 +82,7 @@ void Component::add_output(const output_pin &out) {
|
|||
pins.push_back(temp);
|
||||
}
|
||||
|
||||
void Component::update_gui(int newval) {
|
||||
void Component::update_gui() {
|
||||
SDL_RenderCopy(m_renderer, m_textures[m_state], NULL, m_rects[m_state]);
|
||||
}
|
||||
|
||||
|
@ -92,16 +90,16 @@ void Component::update_state() {
|
|||
Pin pin = *(pins.begin());
|
||||
int newval = (m_interface_type == INPUT_TYPE) ? input_map[pin.m_in] : output_map[pin.m_out];
|
||||
if (newval != m_state) {
|
||||
m_state = newval;
|
||||
update_gui(newval);
|
||||
set_state(newval);
|
||||
update_gui();
|
||||
}
|
||||
}
|
||||
|
||||
RGB_LED::RGB_LED(SDL_Renderer *rend, int cnt, int init_val, int it, int ct)
|
||||
: Component(rend, cnt, init_val, it, ct){}
|
||||
|
||||
void RGB_LED::update_gui(int newval) {
|
||||
SDL_RenderCopy(get_renderer(), get_texture(newval), NULL, get_rect(newval));
|
||||
void RGB_LED::update_gui() {
|
||||
SDL_RenderCopy(get_renderer(), get_texture(get_state()), NULL, get_rect(get_state()));
|
||||
}
|
||||
|
||||
void RGB_LED::update_state() {
|
||||
|
@ -110,15 +108,16 @@ void RGB_LED::update_state() {
|
|||
newval = (newval << 1) | output_map[get_output(i)];
|
||||
}
|
||||
if (newval != get_state()) {
|
||||
update_gui(newval);
|
||||
set_state(newval);
|
||||
update_gui();
|
||||
}
|
||||
}
|
||||
|
||||
SEGS7::SEGS7(SDL_Renderer *rend, int cnt, int init_val, int it, int ct)
|
||||
: Component(rend, cnt, init_val, it, ct){}
|
||||
|
||||
void SEGS7::update_gui(int newval) {
|
||||
void SEGS7::update_gui() {
|
||||
int newval = get_state();
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
if ((newval >> i) & 1) {
|
||||
SDL_RenderCopy(get_renderer(), get_texture(i), NULL, get_rect(i));
|
||||
|
@ -136,8 +135,8 @@ void SEGS7::update_state() {
|
|||
}
|
||||
}
|
||||
if (newval != get_state()) {
|
||||
update_gui(newval);
|
||||
set_state(newval);
|
||||
update_gui();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -248,6 +247,18 @@ void init_components(SDL_Renderer *renderer) {
|
|||
ptr->add_output(output_pin(int(output_pin::AN0) + i));
|
||||
components.push_back(ptr);
|
||||
}
|
||||
|
||||
#ifdef VGA_ENA
|
||||
// init vga
|
||||
ptr = new VGA(renderer, 1, 0, OUTPUT_TYPE, VGA_TYPE);
|
||||
rect_ptr = new SDL_Rect;
|
||||
*rect_ptr = (SDL_Rect){WINDOW_WIDTH, 0, VGA_DEFAULT_WIDTH, VGA_DEFAULT_HEIGHT};
|
||||
ptr->set_rect(rect_ptr, 0);
|
||||
for (output_pin p = output_pin::VGA_CLK; p <= output_pin::VGA_B; p = output_pin(int(p) + 1)) {
|
||||
ptr->add_output(p);
|
||||
}
|
||||
components.push_back(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void delete_components() {
|
||||
|
|
60
src/main.cpp
60
src/main.cpp
|
@ -16,21 +16,24 @@ int main() {
|
|||
// init SDL and SDL_image
|
||||
SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_EVENTS);
|
||||
IMG_Init(IMG_INIT_PNG);
|
||||
VGA *vga = new VGA();
|
||||
|
||||
//std::cerr << "ok\n";
|
||||
SDL_Window *main_window = nullptr;
|
||||
SDL_Renderer *main_renderer = nullptr;
|
||||
main_window = SDL_CreateWindow("nvboard", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN);
|
||||
main_renderer = SDL_CreateRenderer(main_window, -1,
|
||||
#ifdef HARDWARE_ACC
|
||||
SDL_RENDERER_ACCELERATED
|
||||
#else
|
||||
SDL_RENDERER_SOFTWARE
|
||||
main_window = SDL_CreateWindow("nvboard", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH * 2, WINDOW_HEIGHT, SDL_WINDOW_SHOWN);
|
||||
main_renderer = SDL_CreateRenderer(main_window, -1,
|
||||
#ifdef VSYNC
|
||||
SDL_RENDERER_PRESENTVSYNC |
|
||||
#endif
|
||||
#ifdef HARDWARE_ACC
|
||||
SDL_RENDERER_ACCELERATED |
|
||||
#else
|
||||
SDL_RENDERER_SOFTWARE |
|
||||
#endif
|
||||
0
|
||||
);
|
||||
|
||||
// To avoid the SDL bugs on hby's linux
|
||||
usleep(200000);
|
||||
//usleep(200000);
|
||||
|
||||
nboard_home = getenv("NBOARD_HOME");
|
||||
|
||||
|
@ -45,23 +48,42 @@ int main() {
|
|||
|
||||
dut_update();
|
||||
update_components(main_renderer);
|
||||
vga->update_vga();
|
||||
//dbg_wait_esc("finish update");
|
||||
|
||||
unsigned nxt_frame_time = SDL_GetTicks();
|
||||
unsigned cur_time = SDL_GetTicks();
|
||||
// the main cycle
|
||||
while (1) {
|
||||
int ev = read_event();
|
||||
bool clock_updated = read_clock();
|
||||
if (ev == -1) {
|
||||
bool halt = false;
|
||||
do {
|
||||
cur_time = SDL_GetTicks();
|
||||
int ev = read_event();
|
||||
if (ev == -1) {
|
||||
halt = true;
|
||||
break;
|
||||
} else if (ev) {
|
||||
dut_update();
|
||||
update_components(main_renderer);
|
||||
}
|
||||
|
||||
if (read_clock()) {
|
||||
dut_update();
|
||||
update_components(main_renderer);
|
||||
}
|
||||
} while (cur_time < nxt_frame_time);
|
||||
if (halt) {
|
||||
break;
|
||||
} else if (ev || clock_updated) {
|
||||
dut_update();
|
||||
update_components(main_renderer);
|
||||
vga->update_vga();
|
||||
}
|
||||
if ((int)(cur_time - nxt_frame_time) > 1000) {
|
||||
nxt_frame_time = cur_time + 1000 / 60;
|
||||
} else {
|
||||
nxt_frame_time += 1000 / 60;
|
||||
}
|
||||
SDL_RenderPresent(main_renderer);
|
||||
}
|
||||
|
||||
delete_components();
|
||||
delete vga;
|
||||
|
||||
|
||||
SDL_DestroyWindow(main_window);
|
||||
SDL_DestroyRenderer(main_renderer);
|
||||
IMG_Quit();
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include <configs.h>
|
||||
#include <component.h>
|
||||
|
||||
#include <event.h>
|
||||
|
||||
extern std::vector<Component *> components;
|
||||
|
||||
SDL_Surface *sbutton_on, *sbutton_off;
|
||||
|
@ -78,7 +80,8 @@ extern std::string nboard_home;
|
|||
void load_background(SDL_Renderer *renderer) {
|
||||
sfpga_background = IMG_Load((nboard_home + "/pic/" + BG_PATH).c_str());
|
||||
tfpga_background = SDL_CreateTextureFromSurface(renderer, sfpga_background);
|
||||
SDL_RenderCopy(renderer, tfpga_background, NULL, NULL);
|
||||
SDL_Rect rect_bg = {0, 0, WINDOW_WIDTH, WINDOW_HEIGHT};
|
||||
SDL_RenderCopy(renderer, tfpga_background, NULL, &rect_bg);
|
||||
|
||||
#ifdef SEG_BKGND_ENA
|
||||
#ifdef SEG_BKGND_CUSTOM
|
||||
|
@ -89,8 +92,8 @@ void load_background(SDL_Renderer *renderer) {
|
|||
#endif
|
||||
|
||||
tseg7_background = SDL_CreateTextureFromSurface(renderer, sseg7_background);
|
||||
SDL_Rect rect = {SEG_X, SEG_Y, SEG_TOT_WIDTH, SEG_TOT_HEIGHT};
|
||||
SDL_RenderCopy(renderer, tseg7_background, NULL, &rect);
|
||||
SDL_Rect rect_seg7 = {SEG_X, SEG_Y, SEG_TOT_WIDTH, SEG_TOT_HEIGHT};
|
||||
SDL_RenderCopy(renderer, tseg7_background, NULL, &rect_seg7);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -165,7 +168,7 @@ extern std::map<output_pin, int> output_map;
|
|||
// render buttons, switches, leds and 7-segs
|
||||
void init_gui(SDL_Renderer *renderer) {
|
||||
for (auto ptr : components) {
|
||||
ptr->update_gui(ptr->get_state());
|
||||
ptr->update_gui();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,5 +176,4 @@ void update_components(SDL_Renderer *renderer) {
|
|||
for (auto ptr : components) {
|
||||
ptr->update_state();
|
||||
}
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
43
src/vga.cpp
43
src/vga.cpp
|
@ -1,6 +1,8 @@
|
|||
#include <vga.h>
|
||||
#include <constrs.h>
|
||||
#include <macro.h>
|
||||
#include <configs.h>
|
||||
#include <cstring>
|
||||
|
||||
VGA_MODE vga_mod_accepted[NR_VGA_MODE] = {
|
||||
[VGA_MODE_640_480] = {
|
||||
|
@ -15,45 +17,36 @@ VGA_MODE vga_mod_accepted[NR_VGA_MODE] = {
|
|||
},
|
||||
};
|
||||
|
||||
VGA::VGA():
|
||||
VGA::VGA(SDL_Renderer *rend, int cnt, int init_val, int it, int ct):
|
||||
Component(rend, cnt, init_val, it, ct),
|
||||
vga_screen_width(VGA_DEFAULT_WIDTH), vga_screen_height(VGA_DEFAULT_HEIGHT),
|
||||
vga_pre_clk(0), vga_pre_hsync(0), vga_pre_vsync(0),
|
||||
vga_pos(0), vga_vaddr(0), vga_haddr(0) {
|
||||
vga_window = SDL_CreateWindow("nboard-vga",
|
||||
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||
vga_screen_width, vga_screen_height,
|
||||
SDL_WINDOW_SHOWN
|
||||
);
|
||||
vga_renderer = SDL_CreateRenderer(vga_window, -1,
|
||||
#ifdef HARDWARE_ACC
|
||||
SDL_RENDERER_ACCELERATED
|
||||
#else
|
||||
SDL_RENDERER_SOFTWARE
|
||||
#endif
|
||||
);
|
||||
vga_texture = SDL_CreateTexture(vga_renderer, SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_TEXTUREACCESS_STATIC, vga_screen_width, vga_screen_height);
|
||||
SDL_Texture *temp_texture = SDL_CreateTexture(rend, SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_TEXTUREACCESS_STATIC, vga_screen_width, vga_screen_height);
|
||||
set_texture(temp_texture, 0);
|
||||
pixels = new uint32_t[vga_screen_width * vga_screen_height];
|
||||
memset(pixels, 0, vga_screen_width * vga_screen_height * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
VGA::~VGA() {
|
||||
SDL_DestroyWindow(vga_window);
|
||||
SDL_DestroyRenderer(vga_renderer);
|
||||
SDL_DestroyTexture(vga_texture);
|
||||
SDL_DestroyTexture(get_texture(0));
|
||||
delete []pixels;
|
||||
}
|
||||
|
||||
void VGA::update_screen() {
|
||||
void VGA::update_gui() {
|
||||
static int frames = 0;
|
||||
frames ++;
|
||||
printf("%d frames\n", frames);
|
||||
SDL_UpdateTexture(vga_texture, NULL, pixels, vga_screen_width * sizeof(uint32_t));
|
||||
SDL_RenderClear(vga_renderer);
|
||||
SDL_RenderCopy(vga_renderer, vga_texture, NULL, NULL);
|
||||
SDL_RenderPresent(vga_renderer);
|
||||
SDL_Texture *temp_texture = get_texture(0);
|
||||
SDL_Renderer *temp_renderer = get_renderer();
|
||||
SDL_Rect *temp_rect = get_rect(0);
|
||||
SDL_UpdateTexture(temp_texture, NULL, pixels, vga_screen_width * sizeof(uint32_t));
|
||||
//SDL_RenderClear(temp_renderer);
|
||||
SDL_RenderCopy(temp_renderer, temp_texture, NULL, temp_rect);
|
||||
}
|
||||
|
||||
void VGA::update_vga() {
|
||||
void VGA::update_state() {
|
||||
int vga_clk = output_map[output_pin::VGA_CLK];
|
||||
int vga_vsync = output_map[output_pin::VGA_VSYNC];
|
||||
int vga_hsync = output_map[output_pin::VGA_HSYNC];
|
||||
|
@ -72,7 +65,7 @@ void VGA::update_vga() {
|
|||
}
|
||||
if(VGA_NEG_EDGE(vsync)) {
|
||||
vga_pos = 0;
|
||||
update_screen();
|
||||
update_gui();
|
||||
}
|
||||
vga_pre_vsync = vga_vsync;
|
||||
vga_pre_clk = vga_clk;
|
||||
|
|
Loading…
Reference in New Issue