(原创)关于用modelsim显示字符的几个问题(Verilog)(perl)(pli)(generate)
这位高手Piazzo的sina微博上用modelsim显示了“花好月圆,中秋快乐”一幅字,我很感兴趣,便也试了一下,但是写的很烂,没有怎么弄成,本来以为我对verilog已经很熟了,但现在才发现,不会的有这么多。我把问题贴出来,希望老师们能够帮我解答。
先贴Piazzo这位老师的图:
再说一下我的想法:
首先是提取字库,从这一点上我便想错了,我想从word里用超大号字抓图,经过图像处理提取字库,但这是比较复杂的。后来经张老师提醒,我才想起来,原来这东西,我以前玩过,见(原创)用友晶的VGA控制器TERASIC_Binary_VGA_Controller显示汉字和ASCII码字符
接下来用pli,把字库里的内容传递过verilog,这一步好做到。
在接下来,在verilog中,根据字库的内容显示波形,这也好说,只不过是有点的地方震荡几下,没点的地方把线拉直就行了。
但是遇到了很多问题没有解决或者不能令我满意:
1. Verilog里怎样把汉字传送给C语言进行处理?
2. 我本想用generate产生16根线的时序,如果这样的话,几十行的代码就可以搞定了,但发现generate不能这样用,例化一段描述时序代码时,每一次执行的时序都得叠加起来,而且里面的变量都弄混了。
最后我只能非常傻逼地用这种方法实现:
Perl语言生成重复代码
在verilog里重写16段这样的代码
效果图如下
Debussy
Modelsim
跟debussy中显示的位序不一样,不知道怎样调,谁能告诉我?
源码如下
Perl的代码
#!/usr/bin/perl
$len = 16;
$wid = 32;
open $tmp, ">tmp.txt";
for( $i = 0 ; $i < $len ; $i = $i + 1){
printf $tmp
"
integer line_%d = 0;
integer offset_%d = 0;
initial begin
ch_dis[%d] <= 1'b0;
#10;
for(offset_%d = 0; offset_%d < \`HZ_NUM ; offset_%d = offset_%d + 1)begin
ch[%d] = \$hello_ma(offset_%d,(15-%d));
for( line_%d = 0 ; line_%d < 16 ; line_%d = line_%d+1)begin
if(ch[%d][line_%d] != 0)
repeat(10) #1 ch_dis[%d] <= ~ch_dis[%d];
else
repeat(10) #1 ch_dis[%d] <= 1'b0;
end
end
#10;
end
",
$i,$i,$i,$i,$i,$i,$i,$i,$i,$i,$i,$i,$i,$i,$i,$i,$i,$i,$i;
}
Verilog的代码
`timescale 1ns/1ps
`define HZ_NUM 9
module hello_ma();
reg [0:15] ch_dis;
reg [0:15] ch [15:0];
integer k;
integer i, j;
initial begin
ch[i] = 0;
//for( i = 1 ; i < 16 ; i = i+1)
//ch[15-i] = $hello_ma(0,i);
end
//genvar m;
//generate for( m = 0 ; m < 16 ; m = m+1) fork
integer line_0 = 0;
integer offset_0 = 0;
initial begin
ch_dis[0] <= 1'b0;
#10;
for(offset_0 = 0; offset_0 < `HZ_NUM ; offset_0 = offset_0 + 1)begin
ch[0] = $hello_ma(offset_0,(15-0));
for( line_0 = 0 ; line_0 < 16 ; line_0 = line_0+1)begin
if(ch[0][line_0] != 0)
repeat(10) #1 ch_dis[0] <= ~ch_dis[0];
else
repeat(10) #1 ch_dis[0] <= 1'b0;
end
end
#10;
$finish;
end
integer line_1 = 0;
integer offset_1 = 0;
initial begin
ch_dis[1] <= 1'b0;
#10;
for(offset_1 = 0; offset_1 < `HZ_NUM ; offset_1 = offset_1 + 1)begin
ch[1] = $hello_ma(offset_1,(15-1));
for( line_1 = 0 ; line_1 < 16 ; line_1 = line_1+1)begin
if(ch[1][line_1] != 0)
repeat(10) #1 ch_dis[1] <= ~ch_dis[1];
else
repeat(10) #1 ch_dis[1] <= 1'b0;
end
end
#10;
end
integer line_2 = 0;
integer offset_2 = 0;
initial begin
ch_dis[2] <= 1'b0;
#10;
for(offset_2 = 0; offset_2 < `HZ_NUM ; offset_2 = offset_2 + 1)begin
ch[2] = $hello_ma(offset_2,(15-2));
for( line_2 = 0 ; line_2 < 16 ; line_2 = line_2+1)begin
if(ch[2][line_2] != 0)
repeat(10) #1 ch_dis[2] <= ~ch_dis[2];
else
repeat(10) #1 ch_dis[2] <= 1'b0;
end
end
#10;
end
integer line_3 = 0;
integer offset_3 = 0;
initial begin
ch_dis[3] <= 1'b0;
#10;
for(offset_3 = 0; offset_3 < `HZ_NUM ; offset_3 = offset_3 + 1)begin
ch[3] = $hello_ma(offset_3,(15-3));
for( line_3 = 0 ; line_3 < 16 ; line_3 = line_3+1)begin
if(ch[3][line_3] != 0)
repeat(10) #1 ch_dis[3] <= ~ch_dis[3];
else
repeat(10) #1 ch_dis[3] <= 1'b0;
end
end
#10;
end
integer line_4 = 0;
integer offset_4 = 0;
initial begin
ch_dis[4] <= 1'b0;
#10;
for(offset_4 = 0; offset_4 < `HZ_NUM ; offset_4 = offset_4 + 1)begin
ch[4] = $hello_ma(offset_4,(15-4));
for( line_4 = 0 ; line_4 < 16 ; line_4 = line_4+1)begin
if(ch[4][line_4] != 0)
repeat(10) #1 ch_dis[4] <= ~ch_dis[4];
else
repeat(10) #1 ch_dis[4] <= 1'b0;
end
end
#10;
end
integer line_5 = 0;
integer offset_5 = 0;
initial begin
ch_dis[5] <= 1'b0;
#10;
for(offset_5 = 0; offset_5 < `HZ_NUM ; offset_5 = offset_5 + 1)begin
ch[5] = $hello_ma(offset_5,(15-5));
for( line_5 = 0 ; line_5 < 16 ; line_5 = line_5+1)begin
if(ch[5][line_5] != 0)
repeat(10) #1 ch_dis[5] <= ~ch_dis[5];
else
repeat(10) #1 ch_dis[5] <= 1'b0;
end
end
#10;
end
integer line_6 = 0;
integer offset_6 = 0;
initial begin
ch_dis[6] <= 1'b0;
#10;
for(offset_6 = 0; offset_6 < `HZ_NUM ; offset_6 = offset_6 + 1)begin
ch[6] = $hello_ma(offset_6,(15-6));
for( line_6 = 0 ; line_6 < 16 ; line_6 = line_6+1)begin
if(ch[6][line_6] != 0)
repeat(10) #1 ch_dis[6] <= ~ch_dis[6];
else
repeat(10) #1 ch_dis[6] <= 1'b0;
end
end
#10;
end
integer line_7 = 0;
integer offset_7 = 0;
initial begin
ch_dis[7] <= 1'b0;
#10;
for(offset_7 = 0; offset_7 < `HZ_NUM ; offset_7 = offset_7 + 1)begin
ch[7] = $hello_ma(offset_7,(15-7));
for( line_7 = 0 ; line_7 < 16 ; line_7 = line_7+1)begin
if(ch[7][line_7] != 0)
repeat(10) #1 ch_dis[7] <= ~ch_dis[7];
else
repeat(10) #1 ch_dis[7] <= 1'b0;
end
end
#10;
end
integer line_8 = 0;
integer offset_8 = 0;
initial begin
ch_dis[8] <= 1'b0;
#10;
for(offset_8 = 0; offset_8 < `HZ_NUM ; offset_8 = offset_8 + 1)begin
ch[8] = $hello_ma(offset_8,(15-8));
for( line_8 = 0 ; line_8 < 16 ; line_8 = line_8+1)begin
if(ch[8][line_8] != 0)
repeat(10) #1 ch_dis[8] <= ~ch_dis[8];
else
repeat(10) #1 ch_dis[8] <= 1'b0;
end
end
#10;
end
integer line_9 = 0;
integer offset_9 = 0;
initial begin
ch_dis[9] <= 1'b0;
#10;
for(offset_9 = 0; offset_9 < `HZ_NUM ; offset_9 = offset_9 + 1)begin
ch[9] = $hello_ma(offset_9,(15-9));
for( line_9 = 0 ; line_9 < 16 ; line_9 = line_9+1)begin
if(ch[9][line_9] != 0)
repeat(10) #1 ch_dis[9] <= ~ch_dis[9];
else
repeat(10) #1 ch_dis[9] <= 1'b0;
end
end
#10;
end
integer line_10 = 0;
integer offset_10 = 0;
initial begin
ch_dis[10] <= 1'b0;
#10;
for(offset_10 = 0; offset_10 < `HZ_NUM ; offset_10 = offset_10 + 1)begin
ch[10] = $hello_ma(offset_10,(15-10));
for( line_10 = 0 ; line_10 < 16 ; line_10 = line_10+1)begin
if(ch[10][line_10] != 0)
repeat(10) #1 ch_dis[10] <= ~ch_dis[10];
else
repeat(10) #1 ch_dis[10] <= 1'b0;
end
end
#10;
end
integer line_11 = 0;
integer offset_11 = 0;
initial begin
ch_dis[11] <= 1'b0;
#10;
for(offset_11 = 0; offset_11 < `HZ_NUM ; offset_11 = offset_11 + 1)begin
ch[11] = $hello_ma(offset_11,(15-11));
for( line_11 = 0 ; line_11 < 16 ; line_11 = line_11+1)begin
if(ch[11][line_11] != 0)
repeat(10) #1 ch_dis[11] <= ~ch_dis[11];
else
repeat(10) #1 ch_dis[11] <= 1'b0;
end
end
#10;
end
integer line_12 = 0;
integer offset_12 = 0;
initial begin
ch_dis[12] <= 1'b0;
#10;
for(offset_12 = 0; offset_12 < `HZ_NUM ; offset_12 = offset_12 + 1)begin
ch[12] = $hello_ma(offset_12,(15-12));
for( line_12 = 0 ; line_12 < 16 ; line_12 = line_12+1)begin
if(ch[12][line_12] != 0)
repeat(10) #1 ch_dis[12] <= ~ch_dis[12];
else
repeat(10) #1 ch_dis[12] <= 1'b0;
end
end
#10;
end
integer line_13 = 0;
integer offset_13 = 0;
initial begin
ch_dis[13] <= 1'b0;
#10;
for(offset_13 = 0; offset_13 < `HZ_NUM ; offset_13 = offset_13 + 1)begin
ch[13] = $hello_ma(offset_13,(15-13));
for( line_13 = 0 ; line_13 < 16 ; line_13 = line_13+1)begin
if(ch[13][line_13] != 0)
repeat(10) #1 ch_dis[13] <= ~ch_dis[13];
else
repeat(10) #1 ch_dis[13] <= 1'b0;
end
end
#10;
end
integer line_14 = 0;
integer offset_14 = 0;
initial begin
ch_dis[14] <= 1'b0;
#10;
for(offset_14 = 0; offset_14 < `HZ_NUM ; offset_14 = offset_14 + 1)begin
ch[14] = $hello_ma(offset_14,(15-14));
for( line_14 = 0 ; line_14 < 16 ; line_14 = line_14+1)begin
if(ch[14][line_14] != 0)
repeat(10) #1 ch_dis[14] <= ~ch_dis[14];
else
repeat(10) #1 ch_dis[14] <= 1'b0;
end
end
#10;
end
integer line_15 = 0;
integer offset_15 = 0;
initial begin
ch_dis[15] <= 1'b0;
#10;
for(offset_15 = 0; offset_15 < `HZ_NUM ; offset_15 = offset_15 + 1)begin
ch[15] = $hello_ma(offset_15,(15-15));
for( line_15 = 0 ; line_15 < 16 ; line_15 = line_15+1)begin
if(ch[15][line_15] != 0)
repeat(10) #1 ch_dis[15] <= ~ch_dis[15];
else
repeat(10) #1 ch_dis[15] <= 1'b0;
end
end
#10;
end
initial
begin
$fsdbDumpfile("tb_hello_ma.fsdb");
$fsdbDumpvars;
end
endmodule
源码和脚本在这里下载