implement 7-segment display
This commit is contained in:
parent
66d294ab85
commit
5ad4f2de85
|
@ -26,10 +26,9 @@ Virtual FPGA需要使用Verilator生成的一些接口。
|
||||||
当你在虚拟FPGA上改变输入(比如拨动一个开关)的时候,
|
当你在虚拟FPGA上改变输入(比如拨动一个开关)的时候,
|
||||||
虚拟FPGA会自动调用`update_input()`,让你编写的模块能够收到这个改变。
|
虚拟FPGA会自动调用`update_input()`,让你编写的模块能够收到这个改变。
|
||||||
模块得到新的输出之后,虚拟FPGA会调用`update_output()`,把模块的输出同步到GUI上。
|
模块得到新的输出之后,虚拟FPGA会调用`update_output()`,把模块的输出同步到GUI上。
|
||||||
|
|
||||||
##### 体验虚拟FPGA
|
##### 体验虚拟FPGA
|
||||||
|
|
||||||
要改变某个按键或开关的状态,可以使用键盘快捷键,也可以点击鼠标。
|
要改变某个按键或开关的状态,可以使用键盘快捷键,将来也可以点击鼠标。
|
||||||
|
|
||||||
#### 参与贡献
|
#### 参与贡献
|
||||||
|
|
||||||
|
|
BIN
build/emu_board
BIN
build/emu_board
Binary file not shown.
|
@ -5,7 +5,7 @@
|
||||||
// You can replace pictures used in GUI
|
// You can replace pictures used in GUI
|
||||||
|
|
||||||
// 640*480 png
|
// 640*480 png
|
||||||
#define BG_PATH "vbg_1.png"
|
#define BG_PATH "vbg_2.png"
|
||||||
|
|
||||||
// png
|
// png
|
||||||
#define VBTN_ON_PATH "vbtn_on.png"
|
#define VBTN_ON_PATH "vbtn_on.png"
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
// png
|
// png
|
||||||
#define SEG_BKGND_ENA
|
#define SEG_BKGND_ENA
|
||||||
//#define SEG_BKGND_CUSTOM
|
#define SEG_BKGND_CUSTOM
|
||||||
#define VSEGLED_BG_PATH "vsegled_bg.png"
|
#define VSEGLED_BG_PATH "vsegled_bg.png"
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -28,9 +28,10 @@ void init_output();
|
||||||
|
|
||||||
#define RGB_LEDS "r16", "g16", "b16", "r17", "g17", "b17"
|
#define RGB_LEDS "r16", "g16", "b16", "r17", "g17", "b17"
|
||||||
|
|
||||||
#define SEG7_LEDS "an0", "an1", "an2", "an3", \
|
#define SEG7_ENBS "an0", "an1", "an2", "an3", \
|
||||||
"an4", "an5", "an6", "an7", \
|
"an4", "an5", "an6", "an7"
|
||||||
"sega", "segb", "segc", "segd", \
|
|
||||||
|
#define SEG7_SEGS "sega", "segb", "segc", "segd", \
|
||||||
"sege", "segf", "segg", "decp"
|
"sege", "segf", "segg", "decp"
|
||||||
|
|
||||||
//#define UART_OUTPUT
|
//#define UART_OUTPUT
|
||||||
|
|
|
@ -31,14 +31,13 @@
|
||||||
#define SEG_VER_HEIGHT 40
|
#define SEG_VER_HEIGHT 40
|
||||||
#define SEG_HOR_WIDTH 40
|
#define SEG_HOR_WIDTH 40
|
||||||
#define SEG_HOR_HEIGHT 2
|
#define SEG_HOR_HEIGHT 2
|
||||||
#define SEG_DOT_WIDTH 2
|
#define SEG_DOT_WIDTH SEG_VER_WIDTH
|
||||||
#define SEG_DOT_HEIGHT 2
|
#define SEG_DOT_HEIGHT SEG_HOR_HEIGHT
|
||||||
|
|
||||||
#define SEG_WIDTH_MARGIN 2
|
#define SEG_SEP 2
|
||||||
#define SEG_HEIGHT_MARGIN 2
|
|
||||||
|
|
||||||
#define SEG_TOT_WIDTH (SEG_WIDTH_MARGIN * 17 + SEG_VER_WIDTH * 24 + SEG_HOR_WIDTH * 8)
|
#define SEG_TOT_WIDTH (SEG_SEP * 17 + SEG_VER_WIDTH * 24 + SEG_HOR_WIDTH * 8)
|
||||||
#define SEG_TOT_HEIGHT (SEG_HEIGHT_MARGIN * 2 + SEG_VER_HEIGHT * 2 + SEG_HOR_HEIGHT)
|
#define SEG_TOT_HEIGHT (SEG_SEP * 2 + SEG_VER_HEIGHT * 2 + SEG_HOR_HEIGHT * 3)
|
||||||
|
|
||||||
void load_background(SDL_Renderer *renderer);
|
void load_background(SDL_Renderer *renderer);
|
||||||
|
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 9.9 KiB |
BIN
pic/vbtn_off.png
BIN
pic/vbtn_off.png
Binary file not shown.
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 12 KiB |
BIN
pic/vbtn_on.png
BIN
pic/vbtn_on.png
Binary file not shown.
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 12 KiB |
|
@ -14,7 +14,7 @@ std::string input_pins[] = {
|
||||||
const int input_size = sizeof(input_pins) / sizeof(std::string);
|
const int input_size = sizeof(input_pins) / sizeof(std::string);
|
||||||
|
|
||||||
std::string output_pins[] = {
|
std::string output_pins[] = {
|
||||||
NAIVE_LEDS, RGB_LEDS, SEG7_LEDS
|
NAIVE_LEDS, RGB_LEDS, SEG7_ENBS, SEG7_SEGS
|
||||||
};
|
};
|
||||||
|
|
||||||
const int output_size = sizeof(output_pins) / sizeof(std::string);
|
const int output_size = sizeof(output_pins) / sizeof(std::string);
|
||||||
|
|
|
@ -11,6 +11,7 @@ TOP_NAME *dut_ptr;
|
||||||
std::string nboard_home;
|
std::string nboard_home;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
printf("nboard v0.1\n");
|
||||||
// init verilog module
|
// init verilog module
|
||||||
dut_ptr = new TOP_NAME;
|
dut_ptr = new TOP_NAME;
|
||||||
|
|
||||||
|
@ -43,7 +44,6 @@ int main() {
|
||||||
update_input(dut_ptr);
|
update_input(dut_ptr);
|
||||||
update_gui_input(render);
|
update_gui_input(render);
|
||||||
dut_ptr->eval();
|
dut_ptr->eval();
|
||||||
printf("out : %d %d %d %d\n", (dut_ptr->out >> 3) & 1, (dut_ptr->out >> 2) & 1, (dut_ptr->out >> 1) & 1, (dut_ptr->out >> 0) & 1);
|
|
||||||
update_output(dut_ptr);
|
update_output(dut_ptr);
|
||||||
update_gui_output(render);
|
update_gui_output(render);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,26 @@ static SDL_Texture *tled_off, *tled_r, *tled_g, *tled_b,
|
||||||
static SDL_Texture *tfpga_background;
|
static SDL_Texture *tfpga_background;
|
||||||
static SDL_Texture *tseg7_background;
|
static SDL_Texture *tseg7_background;
|
||||||
|
|
||||||
|
static SDL_Rect segs_rect[8] = {
|
||||||
|
{SEG_X + SEG_SEP + SEG_VER_WIDTH, SEG_Y + SEG_SEP, SEG_HOR_WIDTH, SEG_HOR_HEIGHT},
|
||||||
|
{SEG_X + SEG_SEP + SEG_VER_WIDTH + SEG_HOR_WIDTH, SEG_Y + SEG_SEP + SEG_HOR_HEIGHT, SEG_VER_WIDTH, SEG_VER_HEIGHT},
|
||||||
|
{SEG_X + SEG_SEP + SEG_VER_WIDTH + SEG_HOR_WIDTH, SEG_Y + SEG_SEP + 2 * SEG_HOR_HEIGHT + SEG_VER_HEIGHT, SEG_VER_WIDTH, SEG_VER_HEIGHT},
|
||||||
|
{SEG_X + SEG_SEP + SEG_VER_WIDTH, SEG_Y + SEG_SEP + 2 * SEG_HOR_HEIGHT + 2 * SEG_VER_HEIGHT, SEG_HOR_WIDTH, SEG_HOR_HEIGHT},
|
||||||
|
{SEG_X + SEG_SEP, SEG_Y + SEG_SEP + 2 * SEG_HOR_HEIGHT + SEG_VER_HEIGHT, SEG_VER_WIDTH, SEG_VER_HEIGHT},
|
||||||
|
{SEG_X + SEG_SEP, SEG_Y + SEG_SEP + SEG_HOR_HEIGHT, SEG_VER_WIDTH, SEG_VER_HEIGHT},
|
||||||
|
{SEG_X + SEG_SEP + SEG_VER_WIDTH, SEG_Y + SEG_SEP + SEG_HOR_HEIGHT + SEG_VER_HEIGHT, SEG_HOR_WIDTH, SEG_HOR_HEIGHT},
|
||||||
|
{SEG_X + 2 * SEG_SEP + 2 * SEG_VER_WIDTH + SEG_HOR_WIDTH, SEG_Y + SEG_SEP + 2 * SEG_HOR_HEIGHT + 2 * SEG_VER_HEIGHT, SEG_DOT_WIDTH, SEG_DOT_HEIGHT}
|
||||||
|
};
|
||||||
|
|
||||||
|
SDL_Rect operator+(const SDL_Rect &A, const SDL_Rect &B) {
|
||||||
|
SDL_Rect ret;
|
||||||
|
ret.x = A.x + B.x;
|
||||||
|
ret.y = A.y + B.y;
|
||||||
|
ret.w = A.w + B.w;
|
||||||
|
ret.h = A.h + B.h;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
extern std::string nboard_home;
|
extern std::string nboard_home;
|
||||||
|
|
||||||
void load_background(SDL_Renderer *renderer) {
|
void load_background(SDL_Renderer *renderer) {
|
||||||
|
@ -131,7 +151,7 @@ std::string input_switches[] = {
|
||||||
static const int switches_cnt = sizeof(input_switches) / sizeof(std::string);
|
static const int switches_cnt = sizeof(input_switches) / sizeof(std::string);
|
||||||
|
|
||||||
static void update_gui_switch(SDL_Renderer *renderer, int index, bool val) {
|
static void update_gui_switch(SDL_Renderer *renderer, int index, bool val) {
|
||||||
index = 15 - index;
|
index = switches_cnt - 1 - index;
|
||||||
SDL_Rect rect = {SWITCH_X + (SWITCH_WIDTH + SWITCH_SEP) * index, SWITCH_Y, SWITCH_WIDTH, SWITCH_HEIGHT};
|
SDL_Rect rect = {SWITCH_X + (SWITCH_WIDTH + SWITCH_SEP) * index, SWITCH_Y, SWITCH_WIDTH, SWITCH_HEIGHT};
|
||||||
SDL_RenderCopy(renderer, val ? tswitch_on : tswitch_off, NULL, &rect);
|
SDL_RenderCopy(renderer, val ? tswitch_on : tswitch_off, NULL, &rect);
|
||||||
}
|
}
|
||||||
|
@ -192,13 +212,19 @@ std::string output_rgb_leds[] = {
|
||||||
RGB_LEDS
|
RGB_LEDS
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string output_seg7_leds[] = {
|
std::string output_seg7_enbs[] = {
|
||||||
SEG7_LEDS
|
SEG7_ENBS
|
||||||
};
|
};
|
||||||
|
const int seg7_enbs_cnt = sizeof(output_seg7_enbs) / sizeof(std::string);
|
||||||
|
|
||||||
|
std::string output_seg7_segs[] = {
|
||||||
|
SEG7_SEGS
|
||||||
|
};
|
||||||
|
const int seg7_segs_cnt = sizeof(output_seg7_segs) / sizeof(std::string);
|
||||||
|
|
||||||
static void update_gui_naive_led(SDL_Renderer *renderer, int index, bool val) {
|
static void update_gui_naive_led(SDL_Renderer *renderer, int index, bool val) {
|
||||||
//std::cout << "update " << index << std::endl;
|
//std::cout << "update " << index << std::endl;
|
||||||
index = 15 - index;
|
index = naive_leds_cnt - 1 - index;
|
||||||
SDL_Rect rect = {LED_X + (LED_WIDTH + LED_SEP) * index, LED_Y, LED_WIDTH, LED_HEIGHT};
|
SDL_Rect rect = {LED_X + (LED_WIDTH + LED_SEP) * index, LED_Y, LED_WIDTH, LED_HEIGHT};
|
||||||
SDL_RenderCopy(renderer, val ? tled_g : tled_off, NULL, &rect);
|
SDL_RenderCopy(renderer, val ? tled_g : tled_off, NULL, &rect);
|
||||||
}
|
}
|
||||||
|
@ -237,6 +263,22 @@ static void update_gui_rgb_led(SDL_Renderer *renderer, int index, int color) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void update_gui_7segs(SDL_Renderer *renderer, int index, bool enable) {
|
||||||
|
SDL_Rect move = {index * (SEG_HOR_WIDTH + SEG_DOT_WIDTH + SEG_SEP * 4), 0, 0, 0};
|
||||||
|
SDL_Rect dst_rect[8];
|
||||||
|
for (int i = 0; i < 8; ++i) {
|
||||||
|
dst_rect[i] = move + segs_rect[i];
|
||||||
|
}
|
||||||
|
SDL_RenderCopy(renderer, (enable && !output_map["sega"]) ? tsegled_hor_on : tsegled_hor_off, NULL, &dst_rect[0]);
|
||||||
|
SDL_RenderCopy(renderer, (enable && !output_map["segb"]) ? tsegled_ver_on : tsegled_ver_off, NULL, &dst_rect[1]);
|
||||||
|
SDL_RenderCopy(renderer, (enable && !output_map["segc"]) ? tsegled_ver_on : tsegled_ver_off, NULL, &dst_rect[2]);
|
||||||
|
SDL_RenderCopy(renderer, (enable && !output_map["segd"]) ? tsegled_hor_on : tsegled_hor_off, NULL, &dst_rect[3]);
|
||||||
|
SDL_RenderCopy(renderer, (enable && !output_map["sege"]) ? tsegled_ver_on : tsegled_ver_off, NULL, &dst_rect[4]);
|
||||||
|
SDL_RenderCopy(renderer, (enable && !output_map["segf"]) ? tsegled_ver_on : tsegled_ver_off, NULL, &dst_rect[5]);
|
||||||
|
SDL_RenderCopy(renderer, (enable && !output_map["segg"]) ? tsegled_hor_on : tsegled_hor_off, NULL, &dst_rect[6]);
|
||||||
|
SDL_RenderCopy(renderer, (enable && !output_map["segb"]) ? tsegled_dot_on : tsegled_dot_off, NULL, &dst_rect[7]);
|
||||||
|
}
|
||||||
|
|
||||||
// After SDL receives the changes of inputs, call update_gui_input()
|
// After SDL receives the changes of inputs, call update_gui_input()
|
||||||
|
|
||||||
// After updating the outputs of module, call update_gui_output()
|
// After updating the outputs of module, call update_gui_output()
|
||||||
|
@ -268,6 +310,14 @@ void update_gui_output(SDL_Renderer *renderer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check seg7s
|
// check seg7s
|
||||||
|
for (int i = 0; i < seg7_enbs_cnt; ++i) {
|
||||||
|
std::string &str = output_seg7_enbs[i];
|
||||||
|
if (output_map.count(str)) {
|
||||||
|
if (output_map[str] || (prev_output_map[str] != output_map[str])) {
|
||||||
|
update_gui_7segs(renderer, i, output_map[str]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SDL_RenderPresent(renderer);
|
SDL_RenderPresent(renderer);
|
||||||
return;
|
return;
|
||||||
|
@ -288,6 +338,10 @@ void init_gui(SDL_Renderer *renderer) {
|
||||||
for (int i = 0; i < naive_leds_cnt; ++i) {
|
for (int i = 0; i < naive_leds_cnt; ++i) {
|
||||||
update_gui_naive_led(renderer, i, 0);
|
update_gui_naive_led(renderer, i, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < seg7_enbs_cnt; ++i) {
|
||||||
|
update_gui_7segs(renderer, i, 0);
|
||||||
|
}
|
||||||
|
|
||||||
SDL_RenderPresent(renderer);
|
SDL_RenderPresent(renderer);
|
||||||
}
|
}
|
Loading…
Reference in New Issue