implement 7-segment display

This commit is contained in:
Sun Jiru 2022-01-17 15:07:03 +08:00
parent 66d294ab85
commit 5ad4f2de85
11 changed files with 72 additions and 19 deletions

View File

@ -26,10 +26,9 @@ Virtual FPGA需要使用Verilator生成的一些接口。
当你在虚拟FPGA上改变输入比如拨动一个开关的时候
虚拟FPGA会自动调用`update_input()`,让你编写的模块能够收到这个改变。
模块得到新的输出之后虚拟FPGA会调用`update_output()`把模块的输出同步到GUI上。
##### 体验虚拟FPGA
要改变某个按键或开关的状态,可以使用键盘快捷键,也可以点击鼠标。
要改变某个按键或开关的状态,可以使用键盘快捷键,将来也可以点击鼠标。
#### 参与贡献

Binary file not shown.

View File

@ -5,7 +5,7 @@
// You can replace pictures used in GUI
// 640*480 png
#define BG_PATH "vbg_1.png"
#define BG_PATH "vbg_2.png"
// png
#define VBTN_ON_PATH "vbtn_on.png"
@ -17,7 +17,7 @@
// png
#define SEG_BKGND_ENA
//#define SEG_BKGND_CUSTOM
#define SEG_BKGND_CUSTOM
#define VSEGLED_BG_PATH "vsegled_bg.png"
#endif

View File

@ -28,9 +28,10 @@ void init_output();
#define RGB_LEDS "r16", "g16", "b16", "r17", "g17", "b17"
#define SEG7_LEDS "an0", "an1", "an2", "an3", \
"an4", "an5", "an6", "an7", \
"sega", "segb", "segc", "segd", \
#define SEG7_ENBS "an0", "an1", "an2", "an3", \
"an4", "an5", "an6", "an7"
#define SEG7_SEGS "sega", "segb", "segc", "segd", \
"sege", "segf", "segg", "decp"
//#define UART_OUTPUT

View File

@ -31,14 +31,13 @@
#define SEG_VER_HEIGHT 40
#define SEG_HOR_WIDTH 40
#define SEG_HOR_HEIGHT 2
#define SEG_DOT_WIDTH 2
#define SEG_DOT_HEIGHT 2
#define SEG_DOT_WIDTH SEG_VER_WIDTH
#define SEG_DOT_HEIGHT SEG_HOR_HEIGHT
#define SEG_WIDTH_MARGIN 2
#define SEG_HEIGHT_MARGIN 2
#define SEG_SEP 2
#define SEG_TOT_WIDTH (SEG_WIDTH_MARGIN * 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_WIDTH (SEG_SEP * 17 + SEG_VER_WIDTH * 24 + SEG_HOR_WIDTH * 8)
#define SEG_TOT_HEIGHT (SEG_SEP * 2 + SEG_VER_HEIGHT * 2 + SEG_HOR_HEIGHT * 3)
void load_background(SDL_Renderer *renderer);

BIN
pic/vbg_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -14,7 +14,7 @@ std::string input_pins[] = {
const int input_size = sizeof(input_pins) / sizeof(std::string);
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);

View File

@ -11,6 +11,7 @@ TOP_NAME *dut_ptr;
std::string nboard_home;
int main() {
printf("nboard v0.1\n");
// init verilog module
dut_ptr = new TOP_NAME;
@ -43,7 +44,6 @@ int main() {
update_input(dut_ptr);
update_gui_input(render);
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_gui_output(render);
}

View File

@ -27,6 +27,26 @@ static SDL_Texture *tled_off, *tled_r, *tled_g, *tled_b,
static SDL_Texture *tfpga_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;
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 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_RenderCopy(renderer, val ? tswitch_on : tswitch_off, NULL, &rect);
}
@ -192,13 +212,19 @@ std::string output_rgb_leds[] = {
RGB_LEDS
};
std::string output_seg7_leds[] = {
SEG7_LEDS
std::string output_seg7_enbs[] = {
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) {
//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_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 updating the outputs of module, call update_gui_output()
@ -268,6 +310,14 @@ void update_gui_output(SDL_Renderer *renderer) {
}
// 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);
return;
@ -289,5 +339,9 @@ void init_gui(SDL_Renderer *renderer) {
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);
}