我的最终目的还是想在FPGA上做一个小游戏,具体做啥还没想好但是需要一些基本的素材,所以先在屏幕上画一个X出来再说,就像下面这个图:
有一个基础的tft模块已经在 【FPGA的小娱乐】tft显示屏生成信号辅助测试阵列 里说明过了,就是提供chan_in作为输入接口的tft_ctrl模块,基于这个模块的接口可以很简单的做出来画矩形的模块:
- module square_gen(
- input [10-1:0]x_point,
- input [10-1:0]y_point,
- input [10-1:0]x_size,
- input [10-1:0]y_size,
- input [8 -1:0]r,
- input [8 -1:0]g,
- input [8 -1:0]b,
- input [10-1:0]hcount,
- input [10-1:0]vcount,
-
- input power_en,
-
- output chan_en,
- output[24-1:0]chan_data
- );
-
- wire [10-1:0]x_left = x_point;
- wire [10-1:0]x_right = (x_point + x_size >= 11'd480) ? 10'd480 : x_point + x_size;
- wire [10-1:0]y_top = y_point;
- wire [10-1:0]y_bottom = (y_point + y_size >= 11'd272) ? 10'd272 : y_point + y_size;
-
- assign chan_en = power_en && (hcount >= x_left) && (hcount < x_right) && (vcount >= y_top) && (vcount < y_bottom);
- assign chan_data = {r,g,b};
- endmodule
那么进一步,画正正当当的直角等腰三角形也很简单:
- module triangle_gen(
- input [10-1:0]x_point,
- input [10-1:0]y_point,
- input [10-1:0]size,
- input [8 -1:0]r,
- input [8 -1:0]g,
- input [8 -1:0]b,
-
- input [10-1:0]hcount,
- input [10-1:0]vcount,
-
- input power_en,
- input [3:0] mode,
-
- output chan_en,
- output[24-1:0]chan_data
- );
-
- wire [10-1:0]p0_x_point;
- wire [10-1:0]p0_y_point;
- wire [10-1:0]p1_x_point;
- wire [10-1:0]p2_y_point;
-
- assign mode0_power = (x_point - hcount < size) && (y_point - vcount < size) && (x_point - hcount + y_point - vcount < size);
- assign mode1_power = (hcount - x_point < size) && (y_point - vcount < size) && (hcount - x_point + y_point - vcount < size);
- assign mode2_power = (x_point - hcount < size) && (vcount - y_point < size) && (x_point - hcount + vcount - y_point < size);
- assign mode3_power = (hcount - x_point < size) && (vcount - y_point < size) && (hcount - x_point + vcount - y_point < size);
-
- assign chan_en = power_en &&
- ((mode[0] & mode0_power) |
- (mode[1] & mode1_power) |
- (mode[2] & mode2_power) |
- (mode[3] & mode3_power));
- assign chan_data = {r,g,b};
-
- endmodule
对四个三角形做任意的例化,很容易就能画出例如下面这样的三角形元素图:
两个基本图形有了之后,X就很容易画了,第一种方式是一个正方形减去四个8个小三角形X,另一种方式就是先画\ /两种线,再合成一个X。我是用的第二种,那么就开始画/,这个的方式也很容易,一个正方形减去左上和右下两个直角等腰三角形;\对应的则是一个正方形减去左下和右上两个直角等腰三角形,两种斜线合成一个模块,代码的核心其实就是assign chan_en = squ_chan_en && ~tri0_chan_en && ~tri1_chan_en:
- module slash_gen(
- input [10-1:0]x_point,
- input [10-1:0]y_point,
- input [10-1:0]size,
- input [10-1:0]sub_size,
- input [8 -1:0]r,
- input [8 -1:0]g,
- input [8 -1:0]b,
-
- input [10-1:0]hcount,
- input [10-1:0]vcount,
-
- input power_en,
- input mode,
-
- output chan_en,
- output[24-1:0]chan_data
- );
-
- wire squ_chan_en;
- square_gen u_squ(
- .x_point (x_point),
- .y_point (y_point),
- .x_size (size),
- .y_size (size),
- .r (r),
- .g (g),
- .b (b),
- .hcount (hcount),
- .vcount (vcount),
- .power_en (power_en),
- .chan_en (squ_chan_en),
- .chan_data ()
- );
-
- wire tri0_chan_en;
- wire [4-1:0] tri0_mode = mode ? 4'b0010 : 4'b1000;
- wire [10-1:0]tri0_x_point = x_point;
- wire [10-1:0]tri0_y_point = mode ? y_point + size : y_point;
- triangle_gen u_tri0(
- .x_point (tri0_x_point),
- .y_point (tri0_y_point),
- .size (size-sub_size),
- .r (r),
- .g (g),
- .b (b),
- .hcount (hcount),
- .vcount (vcount),
- .power_en (power_en),
- .mode (tri0_mode),
- .chan_en (tri0_chan_en),
- .chan_data ()
- );
-
- wire tri1_chan_en;
- wire [4-1:0] tri1_mode = mode ? 4'b0100 : 4'b0001;
- wire [10-1:0]tri1_x_point = x_point+size;
- wire [10-1:0]tri1_y_point = mode ? y_point : y_point+size;
- triangle_gen u_tri1(
- .x_point (tri1_x_point),
- .y_point (tri1_y_point),
- .size (size-sub_size),
- .r (r),
- .g (g),
- .b (b),
- .hcount (hcount),
- .vcount (vcount),
- .power_en (power_en),
- .mode (tri1_mode),
- .chan_en (tri1_chan_en),
- .chan_data ()
- );
-
- assign chan_en = power_en && (squ_chan_en && ~tri0_chan_en && ~tri1_chan_en);
- assign chan_data = {r,g,b};
-
- endmodule
然后再例化两个斜线,对应的X就出来了:
- module x_gen(
- input [10-1:0]x_point,
- input [10-1:0]y_point,
- input [10-1:0]size,
- input [10-1:0]sub_size,
- input [8 -1:0]r,
- input [8 -1:0]g,
- input [8 -1:0]b,
-
- input [10-1:0]hcount,
- input [10-1:0]vcount,
-
- input power_en,
-
- output chan_en,
- output[24-1:0]chan_data
- );
-
- wire [1 -1:0]slash0_chan_in;
- slash_gen u_slash0(
- .x_point (x_point),
- .y_point (y_point),
- .size (size),
- .sub_size (sub_size),
- .r (r),
- .g (g),
- .b (b),
- .hcount (hcount),
- .vcount (vcount),
- .power_en (1'b1),
- .mode (1'b0),
- .chan_en (slash0_chan_in),
- .chan_data ()
- );
-
- wire [1 -1:0]slash1_chan_in;
- slash_gen u_slash1(
- .x_point (x_point),
- .y_point (y_point),
- .size (size),
- .sub_size (sub_size),
- .r (r),
- .g (g),
- .b (b),
- .hcount (hcount),
- .vcount (vcount),
- .power_en (1'b1),
- .mode (1'b1),
- .chan_en (slash1_chan_in),
- .chan_data ()
- );
-
- assign chan_en = power_en && (slash0_chan_in || slash1_chan_in);
- assign chan_data = {r,g,b};
-
- endmodule
在工程里跑一下,输出就是下图: