2022年09月10日是中秋节。使用modelsim仿真,在波形图上显示"中秋节快乐!"。
小工程不复杂,由取字模、ASCII.v显示像素模块、tb_ASCII.v仿真模块三部分构成。
一、取字模:
取模方式选择逐行扫描,高位在前,十六进制。
生成"节"和"!"两个字,每个字的像素点阵列是16行、64列。所以"节"的第一行是0820,第二行是0820...最后一行是0200。
{0x08,0x20,0x08,0x20,0xFF,0xFE,0x08,0x20,0x08,0x20,0x00,0x00,0x7F,0xF8,0x02,0x08,0x02,0x08,0x02,0x08,0x02,0x08,0x02,0x50,0x02,0x20,0x02,0x00,0x02,0x00,0x02,0x00},/*"节",0*/
{0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
二、ASCII.v显示像素模块:
只有一个always块,是每过一个clk周期,输出一个像素。
而像素具体是0还是1,则需要用后面的assign决断。
module ASCII#(
parameter ASCII_COL_CNT = 16'd64, //一行几位bit?
parameter TURE = 1'b1 //阴阳码选择开关
)(
input clk, //系统时钟
input RSTn,
input ASCII_roll_clk, //电亮一个bit位需要的电平翻转频率时钟(高频)
input [ASCII_COL_CNT-1:0] din, //所有字的第一行bit流
output dout //输出一行,在波形图上显示出来
);
//**********************************************
// 每一行的bit位计数器
//**********************************************
reg [15:0] col_cnt;
always @ (posedge clk or negedge RSTn) begin
if(!RSTn)
col_cnt<=16'd0;
else if(col_cnt==ASCII_COL_CNT-1)
col_cnt<=col_cnt;
else
col_cnt<=col_cnt+1'b1;
end
//**********************************************
// 显示出像素
//**********************************************
wire dout_posedge,dout_negedge; //dout_posedge是阳码显示,dout_negedge是阴码显示
assign dout_posedge = (din[ASCII_COL_CNT-1-col_cnt]==1'b1) ? ASCII_roll_clk : 1'b1; //比特位为0时,像素显示亮,否则显示灭
assign dout_negedge = (din[ASCII_COL_CNT-1-col_cnt]==1'b1) ? 1'b1 : ASCII_roll_clk;
assign dout = (TURE==1'b1) ? dout_posedge : dout_negedge; //阴阳码选择开关
endmodule
三、 tb_ASCII.v仿真模块:
(1)产生10M的clk、500M的ASCII_roll_clk;
(2)产生复位;
(3)产生字库;
(4)用generate函数遍历ASCII.v模块16遍,相当于连续扫描16行;
`timescale 1ns/1ps
module tb_ASCII();
reg clk;
reg RSTn;
reg ASCII_roll_clk;
reg [95:0] din[15:0];
wire [15:0] dout;
always #50 clk = ~clk; //系统时钟10M
initial clk = 0;
always #1 ASCII_roll_clk = ~ASCII_roll_clk; //像素电亮翻转时钟500M
initial ASCII_roll_clk = 0;
initial begin
din[15]=96'h0100_0840_0820_1040_0020_0000;//"中秋节快乐!" 的第一行像素,96位从左到右也是汉字第一行像素的电亮顺序
din[14]=96'h0100_1C40_0820_1040_00F0_1000;//"中秋节快乐!" 的第二行像素
din[13]=96'h0100_F040_FFFE_1040_1F00_1000;
din[12]=96'h0100_1040_0820_13F8_1000_1000;
din[11]=96'h3FF8_1144_0820_1848_1100_1000;
din[10]=96'h2108_FD44_0000_5448_2100_1000;
din[9] =96'h2108_1148_7FF8_5048_2100_1000;
din[8] =96'h2108_3250_0208_5048_3FFC_1000;
din[7] =96'h2108_3840_0208_97FE_0100_1000;
din[6] =96'h2108_54A0_0208_1040_0920_1000;
din[5] =96'h3FF8_54A0_0208_10A0_0910_0000;
din[4] =96'h2108_9090_0250_10A0_1108_0000;
din[3] =96'h0100_1110_0220_1110_2104_1000;
din[2] =96'h0100_1108_0200_1110_4104_1000;
din[1] =96'h0100_1204_0200_1208_0500_0000;
din[0] =96'h0100_1402_0200_1406_0200_0000;//"中秋节快乐!" 的第16行像素也是最后一行像素
end
initial begin
RSTn=0;
#100;
RSTn=1;
#10000;
end
generate
genvar i;
for(i=0;i<16;i=i+1)begin:ASCII_geneeate
ASCII #(96,1)ASCII_u0( clk,RSTn,ASCII_roll_clk,din[i],dout[i] );
end
endgenerate
endmodule
四、最终效果