基于FPGA的信号波形发生器,通过二进制进行显示汉字,可以显示任意汉字,需要的可以来哟!通过quarter9.0进行编程仿真,可以仿真出汉字模型!

最近在实验室折腾FPGA的时候,发现个挺有意思的玩法——用信号波形发生器在示波器上直接显示汉字。这可比普通数字管显示酷多了,关键还能自定义显示内容。今天就给大家掰扯掰扯怎么用Verilog在FPGA上实现这个骚操作。

先说说核心思路。汉字显示本质上就是把字形转换成坐标点的亮灭状态,这个咱们可以用16x16点阵来实现。每个汉字对应256个二进制位,1表示点亮,0就是熄灭。比如"汉"字的字模数据大概是这样的:

parameter [255:0] HANZI_HAN = {
    8'h00,8'h20,8'h10,8'h0C,8'h43,8'h80,8'h60,8'h1E,
    8'h01,8'h01,8'h7F,8'h01,8'h01,8'h01,8'h01,8'h01,
    8'h00,8'h00,8'h00,8'hFE,8'h00,8'h00,8'h00,8'h00,
    8'h40,8'h20,8'h10,8'h0C,8'h03,8'h00,8'h00,8'h00
};

这个数据块看着像天书?其实每个十六进制数对应一行8个像素的状态。比如0x7F转二进制是01111111,对应中间六个像素点亮,两边熄灭。把这些数据存到FPGA的ROM里,就相当于建了个汉字库。

基于FPGA的信号波形发生器,通过二进制进行显示汉字,可以显示任意汉字,需要的可以来哟!通过quarter9.0进行编程仿真,可以仿真出汉字模型!

接下来要搞个扫描控制器,这才是重头戏。核心代码大概长这样:

module display_controller(
    input clk,
    output reg [15:0] row,
    output reg [15:0] col
);

reg [4:0] cnt = 0;

always @(posedge clk) begin
    cnt <= cnt + 1;
    // 行扫描
    row <= 16'h0001 << cnt[3:0]; 
    // 列数据输出
    col <= char_data[cnt]; 
    
    if(cnt == 31) cnt <= 0;
end

endmodule

这个模块每16个时钟周期完成一次全屏刷新。cnt既控制行扫描位置,又作为字模数据的索引。行信号像探照灯一样逐行扫描,列数据同步输出对应行的像素状态。实际用示波器看的话,X轴接行扫描信号,Y轴接列数据,就能在屏幕上拼出完整汉字。

仿真的时候用Quartus自带的SignalTap抓波形特别有意思。把行、列信号设置成模拟波形显示,直接就能看到汉字轮廓。比如设置成"电"字的时候,波形图会呈现出明显的"闪电"形状的跳变沿。

最后说下字库扩展的骚操作。不想手动敲二进制数据的,可以用UCDOS的HZK16字库,直接转成.mif文件导入FPGA。Python写个转换脚本就搞定:

with open('hzk16', 'rb') as f:
    data = f.read()
    offset = (94*(qh-1)+(wh-1))*32
    print(''.join([f'{x:02X}' for x in data[offset:offset+32]]))

这个方案实测在Cyclone IV上跑50MHz时钟完全无压力,动态显示效果比LCD还流畅。想要显示生僻字?直接把转换后的数据往ROM里一扔,想显示什么就显示什么。手头有FPGA开发板的同学可以试试,示波器上跳出汉字的那一刻绝对有惊喜。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐