Merge branch 'vga' of github.com:NJU-ProjectN/nvboard into vga

This commit is contained in:
201220107-贺柄毓 2022-01-26 23:02:25 +08:00
commit 9799b40fb9
8 changed files with 119 additions and 74 deletions

View File

@ -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();
};

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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() {

View File

@ -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();

View File

@ -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);
}

View File

@ -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;