至简设计系列_BCD译码实现

–作者:肖肖肖
本文为明德扬原创及录用文章,转载请注明出处!

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 系统结构框图

系统结构框图如下图一所示:
在这里插入图片描述

图一

1.1.4 模块功能

串口接收模块实现功能
1、接收上位机PC发来的位宽为8的十六进制数据。
BCD译码模块实现功能
1、对接收到的8位十六进制数据进行BCD译码。
数码管显示模块实现功能
1、显示BCD译码后的十进制数值。

1.1.5 顶层信号

信号名I/O位宽定义
clkI1系统工作时钟 50M
rst_nI1系统复位信号,低电平有效
rx_uartI11bit串口接收数据
SegmentO88位数码管段选信号
Seg_selO33位数码管位选信号

1.1.6 参考代码

下面是使用工程的顶层代码:

1.module top(
2.    clk     ,
3.    rst_n   ,
4.    rx_uart ,
5.    seg_sel ,
6.    segment
7.    );
8.
9.    parameter      DATA_W         =         8;
10.    parameter      SEG_WID        =         8;
11.    parameter      SEL_WID        =         3;
12.    parameter      BCD_OUT        =        12;
13.
14.    input                clk      ;
15.    input                rst_n    ;
16.    input                rx_uart  ;
17.
18.    output[SEL_WID-1:0]  seg_sel  ;
19.    output[SEG_WID-1:0]  segment  ;
20.
21.    wire   [SEL_WID-1:0]  seg_sel  ;
22.    wire   [SEG_WID-1:0]  segment  ;
23.
24.    wire  [DATA_W-1 :0]  rx_dout        ;
25.    wire                 rx_dout_vld    ;
26.    wire  [BCD_OUT-1:0]  bcd_dout       ;
27.    wire                 bcd_dout_vld   ;
28.
29.    uart_rx     u1(
30.        .clk          (  clk             ),
31.        .rst_n        (  rst_n           ),
32.        .din          (  rx_uart         ),
33.        .dout         (  rx_dout         ),
34.        .dout_vld     (  rx_dout_vld     )
35.    );
36.
37.    bcd_water   u2(
38.        .clk          (  clk             ),
39.        .rst_n        (  rst_n           ),
40.        .din          (  rx_dout         ),
41.        .din_vld      (  rx_dout_vld     ),
42.        .dout         (  bcd_dout        ),
43.        .dout_vld     (  bcd_dout_vld    )
44.    );
45.
46.    seg_disp    u3(
47.        .clk          (  clk             ),
48.        .rst_n        (  rst_n           ),
49.        .din          (  bcd_dout        ),
50.        .din_vld      (  bcd_dout_vld    ),
51.        .seg_sel      (  seg_sel         ),
52.        .segment      (  segment         ) 
53.    );
54.
55.
56.endmodule

1.2 串口接收模块设计

1.2.1 接口信号

信号名I/O位宽定义
clkI1系统工作时钟 50M
rst_nI1系统复位信号,低电平有效
dinI11bit串口接收数据
doutO88bit的输出数据
dout_vldO1输出数据有效指示信号

1.2.2 设计思路

在前面的案例中已经有串口接收模块的介绍,所以这里不在过多介绍,详细介绍请看下方链接:
http://www.fpgabbs.cn/forum.php?mod=viewthread&tid=1074&fromuid=100105

1.2.3 参考代码

1.module uart_rx(
2.    clk      ,
3.    rst_n    ,
4.    din      ,
5.    dout     ,
6.    dout_vld
7.    );
8.
9.parameter          DATA_W = 8    ;
10.parameter          NUM_W  = 4    ;
11.parameter          CNT_W  = 14   ;
12.parameter    	   BPS	  =	5208 ;	
13.parameter 	       BPS_P  = BPS/2;	
14.
15.input               clk          ;		
16.input               rst_n        ;	
17.input               din          ;
18.output[DATA_W-1:0]  dout         ;		
19.output              dout_vld     ;
20.
21.reg   [DATA_W-1:0]  dout         ;
22.reg                 dout_vld     ;
23.reg   [NUM_W-1 :0]  data_num     ;
24.reg   [DATA_W-1:0]  rx_temp_data ;
25.reg                 din_ff0      ;	
26.reg                 din_ff1      ;	
27.reg                 din_ff2      ;	
28.reg                 flag_add     ;
29.wire                end_cnt      ;
30.wire                end_cnt_p    ;
31.wire                add_data_num ;
32.wire                end_data_num ;
33.
34.reg   [CNT_W-1:0]   cnt          ;	
35.wire                add_cnt      ;
36.always @ (posedge clk or negedge rst_n) begin
37.	if(!rst_n) begin
38.		din_ff0 <= 1'b1;
39.        din_ff1 <= 1'b1;
40.        din_ff2 <= 1'b1;
41.	end
42.	else begin
43.		din_ff0 <= din;
44.        din_ff1 <= din_ff0;
45.        din_ff2 <= din_ff1;
46.	end
47.end
48.
49.always @ (posedge clk or negedge rst_n)begin
50.	if(!rst_n) begin
51.		flag_add <= 1'b0;
52.	end
53.	else if(din_ff2 & ~din_ff1) begin		
54.		flag_add <= 1'b1;	
55.	end
56.	else if(data_num==4'd8&&end_cnt) begin		
57.		flag_add <= 1'b0;	
58.	end
59.end
60.
61.always @ (posedge clk or negedge rst_n)begin
62.    if(!rst_n)begin
63.        cnt <= 0;
64.    end
65.    else if(add_cnt)begin
66.        if(end_cnt)begin
67.            cnt <= 0;	 
68.        end
69.        else begin
70.            cnt <= cnt+1'b1; 
71.        end
72.    end
73.    else begin
74.        cnt <= 0; 
75.    end
76.end
77.assign add_cnt = flag_add;
78.assign end_cnt = add_cnt && cnt == BPS-1;
79.
80.
81.
82.always @(posedge clk or negedge rst_n) begin 
83.    if (rst_n==0) begin
84.        data_num <= 0; 
85.    end
86.    else if(add_data_num) begin
87.        if(end_data_num)
88.            data_num <= 0; 
89.        else
90.            data_num <= data_num+1 ;
91.   end
92.end
93.assign add_data_num = end_cnt;
94.assign end_data_num = add_data_num  && data_num == 9-1 ;
95.
96.always @ (posedge clk or negedge rst_n)begin
97.	if(!rst_n) begin
98.		dout <= 8'd0;
99.	end
100.	else if(add_cnt && cnt==BPS_P-1 && data_num!=0) begin		
101.	    dout<={din,{dout[7:1]}};
102.	end
103.    else begin
104.        dout<=dout; 
105.    end
106.end
107.
108.always @ (posedge clk or negedge rst_n)begin
109.	if(!rst_n) begin
110.		dout_vld <= 1'b0;
111.	end
112.    else if(add_data_num && data_num == 4'd8) begin		
113.		dout_vld <= 1'b1;	
114.	end
115.	else begin	
116.        dout_vld <= 1'b0;			
117.	end
118.end
119.endmodule

1.3 BCD译码模块设计

1.3.1 接口信号

信号名I/O位宽定义
clkI1系统工作时钟 50M
rst_nI1系统复位信号,低电平有效
dinI88bit的输入数据
din_vldI1输入数据有效指示信号
doutO1212bit的输出BCD译码数据,每 4 bit一组,分别表示百、十、个位的值
dout_vldO1输出数据有效指示信号

1.3.2 设计思路

左移加3算法
此处二进制转 BCD 码的硬件实现,采用左移加 3 的算法,具体描述如下:(此处以 8-bit 二进制码为例)
1、左移要转换的二进制码 1 位
2、左移之后,BCD 码分别置于百位、十位、个位
3、如果移位后所在的 BCD 码列大于或等于 5,则对该值加 3
4、继续左移的过程直至全部移位完成

举例:将十六进制码 0xFF 转换成 BCD 码
在这里插入图片描述

1.3.3 参考代码

1.module bcd_water(
2.        clk     ,
3.        rst_n   ,
4.        din     ,
5.        din_vld ,
6.        dout    ,
7.        dout_vld
8.    );
9.input                   clk                 ;
10.input                   rst_n               ;
11.input       [ 7:0]      din                 ;
12.input                   din_vld             ;
13.output      [11:0]      dout                ;
14.wire        [11:0]      dout                ;
15.output                  dout_vld            ;
16.wire                    dout_vld            ;
17.reg         [19:0]      din_temp            ;
18.reg         [19:0]      din_temp_ff0        ;
19.reg         [19:0]      din_temp_ff1        ;
20.reg         [19:0]      din_temp_ff2        ;
21.reg         [19:0]      din_temp_ff3        ;
22.reg         [19:0]      din_temp_ff4        ;
23.wire        [20:0]      din_shift_temp      ;
24.wire        [20:0]      din_shift_temp_ff0  ;
25.wire        [20:0]      din_shift_temp_ff1  ;
26.wire        [20:0]      din_shift_temp_ff2  ;
27.wire        [20:0]      din_shift_temp_ff3  ;
28.wire        [ 7:0]      din_a_temp          ;
29.wire        [ 3:0]      din_b_temp          ;
30.wire        [ 3:0]      din_c_temp          ;
31.wire        [ 3:0]      din_d_temp          ;
32.wire        [ 7:0]      din_add_a_temp      ;
33.wire        [ 3:0]      din_add_b_temp      ;
34.wire        [ 3:0]      din_add_c_temp      ;
35.wire        [ 3:0]      din_add_d_temp      ;
36.
37.wire        [ 7:0]      din_a_temp_ff0      ;
38.wire        [ 3:0]      din_b_temp_ff0      ;
39.wire        [ 3:0]      din_c_temp_ff0      ;
40.wire        [ 3:0]      din_d_temp_ff0      ;
41.wire        [ 7:0]      din_a_temp_ff1      ;
42.wire        [ 3:0]      din_b_temp_ff1      ;
43.wire        [ 3:0]      din_c_temp_ff1      ;
44.wire        [ 3:0]      din_d_temp_ff1      ;
45.wire        [ 7:0]      din_a_temp_ff2      ;
46.wire        [ 3:0]      din_b_temp_ff2      ;
47.wire        [ 3:0]      din_c_temp_ff2      ;
48.wire        [ 3:0]      din_d_temp_ff2      ;
49.wire        [ 7:0]      din_a_temp_ff3      ;
50.wire        [ 3:0]      din_b_temp_ff3      ;
51.wire        [ 3:0]      din_c_temp_ff3      ;
52.wire        [ 3:0]      din_d_temp_ff3      ;
53.wire        [ 7:0]      din_add_a_temp_ff0  ;
54.wire        [ 3:0]      din_add_b_temp_ff0  ;
55.wire        [ 3:0]      din_add_c_temp_ff0  ;
56.wire        [ 3:0]      din_add_d_temp_ff0  ;
57.wire        [ 7:0]      din_add_a_temp_ff1  ;
58.wire        [ 3:0]      din_add_b_temp_ff1  ;
59.wire        [ 3:0]      din_add_c_temp_ff1  ;
60.wire        [ 3:0]      din_add_d_temp_ff1  ;
61.wire        [ 7:0]      din_add_a_temp_ff2  ;
62.wire        [ 3:0]      din_add_b_temp_ff2  ;
63.wire        [ 3:0]      din_add_c_temp_ff2  ;
64.wire        [ 3:0]      din_add_d_temp_ff2  ;
65.wire        [ 7:0]      din_add_a_temp_ff3  ;
66.wire        [ 3:0]      din_add_b_temp_ff3  ;
67.wire        [ 3:0]      din_add_c_temp_ff3  ;
68.wire        [ 3:0]      din_add_d_temp_ff3  ;
69.reg                     dout_vld_temp       ;
70.reg                     dout_vld_temp_ff0   ;
71.reg                     dout_vld_temp_ff1   ;
72.reg                     dout_vld_temp_ff2   ;
73.reg                     dout_vld_temp_ff3   ;
74.reg                     dout_vld_temp_ff4   ;
75.	 
76.always  @(posedge clk or negedge rst_n)begin
77.    if(rst_n==1'b0)begin
78.        din_temp <= 20'b0;
79.    end
80.    else if(din_vld)begin
81.        din_temp <= {9'b0,din,3'b0};
82.    end
83.end
84.always  @(posedge clk or negedge rst_n)begin
85.    if(rst_n==1'b0)begin
86.        dout_vld_temp <= 1'b0;
87.    end
88.    else if(din_vld)begin
89.        dout_vld_temp <= 1'b1;
90.    end
91.    else begin
92.        dout_vld_temp <= 1'b0;
93.    end
94.end
95.assign  din_a_temp     = din_temp[ 7: 0]                                                     ;
96.assign  din_b_temp     = din_temp[11: 8]                                                     ;
97.assign  din_c_temp     = din_temp[15:12]                                                     ;
98.assign  din_d_temp     = din_temp[19:16]                                                     ;
99.assign  din_add_a_temp = din_a_temp                                                          ;
100.assign  din_add_b_temp = din_b_temp + ((din_b_temp>=5)?4'd3:4'd0)                            ;
101.assign  din_add_c_temp = din_c_temp + ((din_c_temp>=5)?4'd3:4'd0)                            ;
102.assign  din_add_d_temp = din_d_temp + ((din_d_temp>=5)?4'd3:4'd0)                            ;
103.assign  din_shift_temp = {din_add_d_temp,din_add_c_temp,din_add_b_temp,din_add_a_temp,1'b0}  ;
104.
105.
106.always  @(posedge clk or negedge rst_n)begin
107.    if(rst_n==1'b0)begin
108.        din_temp_ff0 <= 20'b0;
109.    end
110.    else begin
111.        din_temp_ff0 <= din_shift_temp[19:0];
112.
113.    end
114.end
115.always  @(posedge clk or negedge rst_n)begin
116.    if(rst_n==1'b0)begin
117.        dout_vld_temp_ff0 <= 1'b0 ;
118.    end
119.    else begin
120.        dout_vld_temp_ff0 <= dout_vld_temp;
121.    end
122.end
123.assign  din_a_temp_ff0     = din_temp_ff0[ 7: 0]                                             ;
124.assign  din_b_temp_ff0     = din_temp_ff0[11: 8]                                             ;
125.assign  din_c_temp_ff0     = din_temp_ff0[15:12]                                             ;
126.assign  din_d_temp_ff0     = din_temp_ff0[19:16]                                             ;
127.assign  din_add_a_temp_ff0 = din_a_temp_ff0                                                  ;
128.assign  din_add_b_temp_ff0 = din_b_temp_ff0 + ((din_b_temp_ff0>=5)?4'd3:4'd0)                ;
129.assign  din_add_c_temp_ff0 = din_c_temp_ff0 + ((din_c_temp_ff0>=5)?4'd3:4'd0)                ;
130.assign  din_add_d_temp_ff0 = din_d_temp_ff0 + ((din_d_temp_ff0>=5)?4'd3:4'd0)                ;
131.assign  din_shift_temp_ff0 = {din_add_d_temp_ff0,din_add_c_temp_ff0,din_add_b_temp_ff0,din_add_a_temp_ff0,1'b0};
132.
133.
134.always  @(posedge clk or negedge rst_n)begin
135.    if(rst_n==1'b0)begin
136.        din_temp_ff1 <= 20'b0;
137.    end
138.    else begin
139.        din_temp_ff1 <= din_shift_temp_ff0[19:0];
140.    end
141.end
142.always  @(posedge clk or negedge rst_n)begin
143.    if(rst_n==1'b0)begin
144.        dout_vld_temp_ff1 <= 1'b0;
145.    end
146.    else begin
147.        dout_vld_temp_ff1 <= dout_vld_temp_ff0;
148.    end
149.end
150.assign  din_a_temp_ff1     = din_temp_ff1[ 7: 0]                                             ;
151.assign  din_b_temp_ff1     = din_temp_ff1[11: 8]                                             ;
152.assign  din_c_temp_ff1     = din_temp_ff1[15:12]                                             ;
153.assign  din_d_temp_ff1     = din_temp_ff1[19:16]                                             ;
154.assign  din_add_a_temp_ff1 = din_a_temp_ff1                                                  ;
155.assign  din_add_b_temp_ff1 = din_b_temp_ff1 + ((din_b_temp_ff1>=5)?4'd3:4'd0)                ;
156.assign  din_add_c_temp_ff1 = din_c_temp_ff1 + ((din_c_temp_ff1>=5)?4'd3:4'd0)                ;
157.assign  din_add_d_temp_ff1 = din_d_temp_ff1 + ((din_d_temp_ff1>=5)?4'd3:4'd0)                ;
158.assign  din_shift_temp_ff1 = {din_add_d_temp_ff1,din_add_c_temp_ff1,din_add_b_temp_ff1,din_add_a_temp_ff1,1'b0};
159.
160.
161.always  @(posedge clk or negedge rst_n)begin 
162.    if(rst_n==1'b0)begin
163.        din_temp_ff2 <= 20'b0;
164.    end
165.    else begin
166.        din_temp_ff2 <= din_shift_temp_ff1[19:0];
167.    end
168.end
169.always  @(posedge clk or negedge rst_n)begin 
170.    if(rst_n==1'b0)begin
171.        dout_vld_temp_ff2 <= 1'b0;
172.    end
173.    else begin
174.        dout_vld_temp_ff2 <= dout_vld_temp_ff1;
175.    end
176.end
177.assign  din_a_temp_ff2     = din_temp_ff2[ 7: 0]                                             ;
178.assign  din_b_temp_ff2     = din_temp_ff2[11: 8]                                             ;
179.assign  din_c_temp_ff2     = din_temp_ff2[15:12]                                             ;
180.assign  din_d_temp_ff2     = din_temp_ff2[19:16]                                             ;
181.assign  din_add_a_temp_ff2 = din_a_temp_ff2                                                  ;
182.assign  din_add_b_temp_ff2 = din_b_temp_ff2 + ((din_b_temp_ff2>=5)?4'd3:4'd0)                ;
183.assign  din_add_c_temp_ff2 = din_c_temp_ff2 + ((din_c_temp_ff2>=5)?4'd3:4'd0)                ;
184.assign  din_add_d_temp_ff2 = din_d_temp_ff2 + ((din_d_temp_ff2>=5)?4'd3:4'd0)                ;
185.assign  din_shift_temp_ff2 = {din_add_d_temp_ff2,din_add_c_temp_ff2,din_add_b_temp_ff2,din_add_a_temp_ff2,1'b0};
186.
187.
188.always  @(posedge clk or negedge rst_n)begin
189.    if(rst_n==1'b0)begin
190.        din_temp_ff3 <= 20'b0;
191.    end
192.    else begin
193.        din_temp_ff3 <= din_shift_temp_ff2[19:0];
194.    end
195.end
196.always  @(posedge clk or negedge rst_n)begin
197.    if(rst_n==1'b0)begin
198.        dout_vld_temp_ff3 <= 1'b0;
199.    end
200.    else begin
201.        dout_vld_temp_ff3 <= dout_vld_temp_ff2;
202.    end
203.end
204.assign  din_a_temp_ff3     = din_temp_ff3[ 7: 0]                                             ;
205.assign  din_b_temp_ff3     = din_temp_ff3[11: 8]                                             ;
206.assign  din_c_temp_ff3     = din_temp_ff3[15:12]                                             ;
207.assign  din_d_temp_ff3     = din_temp_ff3[19:16]                                             ;
208.assign  din_add_a_temp_ff3 = din_a_temp_ff3                                                  ;
209.assign  din_add_b_temp_ff3 = din_b_temp_ff3 + ((din_b_temp_ff3>=5)?4'd3:4'd0)                ;
210.assign  din_add_c_temp_ff3 = din_c_temp_ff3 + ((din_c_temp_ff3>=5)?4'd3:4'd0)                ;
211.assign  din_add_d_temp_ff3 = din_d_temp_ff3 + ((din_d_temp_ff3>=5)?4'd3:4'd0)                ;
212.assign  din_shift_temp_ff3 = {din_add_d_temp_ff3,din_add_c_temp_ff3,din_add_b_temp_ff3,din_add_a_temp_ff3,1'b0};
213.
214.
215.always  @(posedge clk or negedge rst_n)begin
216.    if(rst_n==1'b0)begin
217.        din_temp_ff4 <= 20'b0;
218.    end
219.    else begin
220.        din_temp_ff4 <= din_shift_temp_ff3[19:0];
221.    end
222.end
223.always  @(posedge clk or negedge rst_n)begin
224.    if(rst_n==1'b0)begin
225.        dout_vld_temp_ff4 <= 1'b0;
226.    end
227.    else begin
228.        dout_vld_temp_ff4 <= dout_vld_temp_ff3;
229.    end
230.end
231.assign  dout     = din_temp_ff4[19:8];
232.assign  dout_vld = dout_vld_temp_ff4 ;
233.
234.
235.endmodule

1.4 数码管显示模块设计

1.4.1 接口信号

信号名I/O位宽定义
clkI1系统工作时钟 50M
rst_nI1系统复位信号,低电平有效
dinI1212位的输入BCD译码数据
din_vldI1输入数据有效指示信号
segmentO88位数码管段选信号
seg_selO33位数码管位选信号

1.4.2 设计思路

在前面的案例中已经有数码管显示的介绍,所以这里不在过多介绍,详细介绍请看下方链接:
http://fpgabbs.com/forum.php?mod=viewthread&tid=399

1.4.3 参考代码

module  seg_disp(
237.                 rst_n       ,
238.                 clk         ,
239.                 din         ,
240.                 din_vld     ,
241.                 seg_sel     ,
242.                 segment      
243.             );
244.
245.
246.parameter  DATA_IN        =       12          ;
247.parameter  TIME_30US      =       1500        ;
248.parameter  SEG_WID        =       8           ;
249.parameter  SEG_NUM        =       3           ;
250.parameter  CNT_WID        =       10          ;
251.
252.parameter  NUM_0          =       8'b1100_0000;
253.parameter  NUM_1          =       8'b1111_1001;
254.parameter  NUM_2          =       8'b1010_0100;
255.parameter  NUM_3          =       8'b1011_0000;
256.parameter  NUM_4          =       8'b1001_1001;
257.parameter  NUM_5          =       8'b1001_0010;
258.parameter  NUM_6          =       8'b1000_0010;
259.parameter  NUM_7          =       8'b1111_1000;
260.parameter  NUM_8          =       8'b1000_0000;
261.parameter  NUM_9          =       8'b1001_0000;
262.parameter  NUM_ERR        =       8'b1111_1111;
263.
264.
265.input                             clk         ;
266.input                             rst_n       ;
267.input  [DATA_IN - 1:0]            din         ;
268.input                             din_vld     ;
269.
270.output [SEG_NUM - 1:0]            seg_sel     ;
271.output [SEG_WID - 1:0]            segment     ;
272.
273.reg    [SEG_NUM - 1:0]            seg_sel     ;
274.reg    [SEG_WID - 1:0]            segment     ;
275.
276.reg    [ 31    :    0]            cnt_30us      ;
277.reg    [SEG_NUM - 1:0]            sel_cnt     ;
278.
279.reg    [ 4 - 1 :    0]            seg_tmp     ;
280.
281.wire                              add_cnt_30us  ;
282.wire                              end_cnt_30us  ;
283.wire                              add_sel_cnt ;
284.wire                              end_sel_cnt ;
285.
286.
287.always @(posedge clk or negedge rst_n) begin 
288.    if (rst_n==0) begin
289.        cnt_30us <= 0; 
290.    end
291.    else if(add_cnt_30us) begin
292.        if(end_cnt_30us)
293.            cnt_30us <= 0; 
294.        else
295.            cnt_30us <= cnt_30us+1 ;
296.   end
297.end
298.assign add_cnt_30us = 1;
299.assign end_cnt_30us = add_cnt_30us  && cnt_30us == TIME_30US-1 ;
300.
301.
302.always  @(posedge clk or negedge rst_n)begin
303.    if(rst_n==1'b0)begin
304.        sel_cnt <= 0;
305.    end
306.    else if(add_sel_cnt)begin
307.        if(end_sel_cnt)
308.            sel_cnt <= 0;
309.        else
310.            sel_cnt <= sel_cnt + 1;
311.    end
312.end
313.assign add_sel_cnt = end_cnt_30us;
314.assign end_sel_cnt = add_sel_cnt && sel_cnt == SEG_NUM-1;
315.
316.always  @(posedge clk or negedge rst_n)begin
317.    if(rst_n==1'b0)begin
318.        seg_sel <= {SEG_NUM{1'b1}};
319.    end
320.    else begin
321.        seg_sel <= ~(1'b1 << sel_cnt);
322.    end
323.end
324.
325.
326.
327.always  @(posedge clk or negedge rst_n)begin
328.    if(rst_n==1'b0)begin
329.        seg_tmp <= 0;
330.    end
331.    else begin
332.        seg_tmp <= din[4*(sel_cnt+1)-1 -:4];
333.    end
334.end
335.
336.
337.always@(posedge clk or negedge rst_n)begin
338.    if(rst_n==1'b0)begin
339.        segment<=NUM_0;
340.    end
341.    else  begin
342.        case (seg_tmp)
343.            0 : segment <= NUM_0;
344.            1 : segment <= NUM_1;
345.            2 : segment <= NUM_2;
346.            3 : segment <= NUM_3;
347.            4 : segment <= NUM_4;
348.            5 : segment <= NUM_5;
349.            6 : segment <= NUM_6;
350.            7 : segment <= NUM_7;
351.            8 : segment <= NUM_8;
352.            9 : segment <= NUM_9;
353.            default : segment <= NUM_ERR;
354.        endcase
355.    end
356.end
357.
358.endmodule

1.5 效果和总结

下图是该工程在db603开发板上的现象——串口发送数据8’h93,数码管显示12’d147。
在这里插入图片描述
在这里插入图片描述

下图是该工程在mp801试验箱上的现象——串口发送数据8’he9,数码管显示12’d233。
在这里插入图片描述
在这里插入图片描述

下图是该工程在ms980试验箱上的现象——串口发送数据8’h52,数码管显示12’d082。
在这里插入图片描述
在这里插入图片描述

由于该项目的上板现象是串口发送8位的十六进制数经过BCD译码后,在数码管上显示对应的十进制数值,想观看完整现象的朋友可以看一下上板演示的视频。
感兴趣的朋友也可以访问论坛进行FPGA相关工程设计学习,也可以看一下我们往期的文章。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值