本文为明德扬原创及录用文章,转载请注明出处!
1.1 总体设计
1.1.1 概述
BCD码(Binary-Coded Decimal),用4位二进制数来表示1位十进制数中的0~9这10个数码,是一种二进制的数字编码形式,用二进制编码的十进制代码。BCD码这种编码形式利用了四个位元来储存一个十进制的数码,使二进制和十进制之间的转换得以快捷的进行。
1.1.2 设计目标
实现BCD译码并显示十进制结果的程序,具体功能要求如下:
1. 串口发送8位十六进制数给FPGA;
2. FPGA接收串口数据并对其进行BCD译码;
3. 在数码管上以十进制显示串口发送的数值。
1.1.3 系统结构框图
系统结构框图如下图一所示:
![0bc9045fa5cf01d5d201c71dca60f394.png](https://i-blog.csdnimg.cn/blog_migrate/fc5985e8687396bace6be2e225b0e9a5.jpeg)
图一
1.1.4模块功能
- 串口接收模块实现功能
1、 接收上位机PC发来的位宽为8的十六进制数据。
- BCD译码模块实现功能
1、 对接收到的8位十六进制数据进行BCD译码。
- 数码管显示模块实现功能
1、 显示BCD译码后的十进制数值。
1.1.5顶层信号
![607289fee5a2c6e0cb928602c857f36c.png](https://i-blog.csdnimg.cn/blog_migrate/3a8884603fac7563d5690e45ed8c2158.jpeg)
1.1.6参考代码
下面是使用工程的顶层代码:
module top( clk , rst_n , rx_uart , seg_sel , segment ); parameter DATA_W = 8; parameter SEG_WID = 8; parameter SEL_WID = 3; parameter BCD_OUT = 12; input clk ; input rst_n ; input rx_uart ; output[SEL_WID-1:0] seg_sel ; output[SEG_WID-1:0] segment ; wire [SEL_WID-1:0] seg_sel ; wire [SEG_WID-1:0] segment ; wire [DATA_W-1 :0] rx_dout ; wire rx_dout_vld ; wire [BCD_OUT-1:0] bcd_dout ; wire bcd_dout_vld ; uart_rx u1( .clk ( clk ), .rst_n ( rst_n ), .din ( rx_uart ), .dout ( rx_dout ), .dout_vld ( rx_dout_vld ) ); bcd_water u2( .clk ( clk ), .rst_n ( rst_n ), .din ( rx_dout ), .din_vld ( rx_dout_vld ), .dout ( bcd_dout ), .dout_vld ( bcd_dout_vld ) ); seg_disp#(.SEG_NUM(SEL_WID)) u3( .clk ( clk ), .rst_n ( rst_n ), .din ( bcd_dout ), .din_vld ( bcd_dout_vld ), .seg_sel ( seg_sel ), .segment ( segment ) );endmodule
1.2 串口接收模块设计
1.2.1接口信号
![1e6d3afbd2d419d0a1a1b7b843f23100.png](https://i-blog.csdnimg.cn/blog_migrate/87a3e103293c8e82aa99dd0a8045b0b1.jpeg)
1.2.2 设计思路
在前面的案例中已经有串口接收模块的介绍,所以这里不在过多介绍,详细介绍请看下方链接:
http://www.fpgabbs.cn/forum.php?mod=viewthread&tid=1074&fromuid=100105
1.2.3参考代码
module uart_rx( clk , rst_n , din , dout , dout_vld );parameter DATA_W = 8 ;parameter NUM_W = 4 ;parameter CNT_W = 14 ;parameter BPS = 5208 ; parameter BPS_P = BPS/2; input clk ; input rst_n ; input din ;output[DATA_W-1:0] dout ; output dout_vld ;reg [DATA_W-1:0] dout ;reg dout_vld ;reg [NUM_W-1 :0] data_num ;reg [DATA_W-1:0] rx_temp_data ;reg din_ff0 ; reg din_ff1 ; reg din_ff2 ; reg flag_add ;wire end_cnt ;wire end_cnt_p ;wire add_data_num ;wire end_data_num ;reg [CNT_W-1:0] cnt ; wire add_cnt ;always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin din_ff0 <= 1'b1; din_ff1 <= 1'b1; din_ff2 <= 1'b1; end else begin din_ff0 <= din; din_ff1 <= din_ff0; din_ff2 <= din_ff1; endendalways @ (posedge clk or negedge rst_n)begin if(!rst_n) begin fl