implement 7-segment display
This commit is contained in:
parent
66d294ab85
commit
5ad4f2de85
|
@ -26,10 +26,9 @@ Virtual FPGA需要使用Verilator生成的一些接口。
|
|||
当你在虚拟FPGA上改变输入(比如拨动一个开关)的时候,
|
||||
虚拟FPGA会自动调用`update_input()`,让你编写的模块能够收到这个改变。
|
||||
模块得到新的输出之后,虚拟FPGA会调用`update_output()`,把模块的输出同步到GUI上。
|
||||
|
||||
##### 体验虚拟FPGA
|
||||
|
||||
要改变某个按键或开关的状态,可以使用键盘快捷键,也可以点击鼠标。
|
||||
要改变某个按键或开关的状态,可以使用键盘快捷键,将来也可以点击鼠标。
|
||||
|
||||
#### 参与贡献
|
||||
|
||||
|
|
BIN
build/emu_board
BIN
build/emu_board
Binary file not shown.
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
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);
|
||||
|
||||
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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -288,6 +338,10 @@ void init_gui(SDL_Renderer *renderer) {
|
|||
for (int i = 0; i < naive_leds_cnt; ++i) {
|
||||
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);
|
||||
}
|
Loading…
Reference in New Issue