Verilog HDL 学习篇——六位数码管驱动

根据原理图可知,此处数码管数据时共享的,每个位由片选信号分隔开,考虑人眼的视觉残留,可用扫描的方式更新数据。

 

这个驱动,有两个比较重要的,就是扫描驱动和二进制转BCD编码了

 

先说扫描驱动吧,要让第一个位现实,则需要打开SEL0_T并输入段码数据,然后输出第二位,第三位……,这里数据刷新的频率不能太高,一则人眼对100Hz以上的信号已不怎么分辨得出来,二则这里的PNP三极管开关速度也是有限制的

(修改代码中) 原地址:http://blog.sina.com.cn/s/blog_450b0ea901013yps.html

 

2013/2/28 14:17

 

扫描模块,这个代码比之前的代码,占用资源更少(少了100个LE的样子大笑,说明以前代码太差了,毕竟那时候初学),

module DIGIT_MODULE (  input   CLK,  input   RST,  input [23:0] BCD,    output [7:0] DIG,  output [5:0] SEL ); assign DIG=rDIG; assign SEL=rSEL; //...................................................................................................................... localparam N0 = 8'B11000000, N1 = 8'b11111001, N2 = 8'b10100100, N3 = 8'b10110000, N4 = 8'b10011001,    N5 = 8'B10010010, N6 = 8'b10000010, N7 = 8'b11111000, N8 = 8'b10000000, N9 = 8'b10010000;

reg [3:0] rBCD; reg [7:0] rDIG; always @(rBCD or RST)  if(!RST) rDIG<=N0;  else case(rBCD)   4'D0:  rDIG<=N0;   4'D1:   rDIG<=N1;   4'D2:   rDIG<=N2;   4'D3:   rDIG<=N3;   4'D4:   rDIG<=N4;   4'D5:   rDIG<=N5;   4'D6:   rDIG<=N6;   4'D7:   rDIG<=N7;   4'D8:   rDIG<=N8;   4'D9:   rDIG<=N9;   default: rDIG<=N0;  endcase //...................................................................................................................... reg[5:0]  rSEL; reg[2:0] rNumber;

always @ (negedge CLK or negedge RST)  if(!RST) begin   rSEL <=6'B111111;   rBCD <=4'D0;   rNumber <=3'H0;  end  else begin   if(rNumber==3'H5) rNumber<=3'H0;   else rNumber<=rNumber+1'B1;      case(rNumber)    3'H0: begin     rSEL<=6'B111110;     rBCD<=BCD[23:20];    end    3'H1: begin     rSEL<=6'B111101;     rBCD<=BCD[19:16];    end    3'H2: begin     rSEL<=6'B111011;     rBCD<=BCD[15:12];    end    3'H3: begin     rSEL<=6'B110111;     rBCD<=BCD[11:8];    end    3'H4: begin     rSEL<=6'B101111;     rBCD<=BCD[7:4];    end    3'H5: begin     rSEL<=6'B011111;     rBCD<=BCD[3:0];    end   endcase  end //...................................................................................................................... endmodule

 

另一个比较重要的就是二进制转BCD(8421)编码,通常使用左移加3的算法,实现方法如图

 

此处有6位数码管,按最大显示的十进制算,需要23bit的二进制来表示,考虑这里速度要求不高,使用时序逻辑操作(代码编写中,非流水线组合逻辑实现请参考http://blog.sina.com.cn/s/blog_450b0ea901013yps.html

 

//======================================================================================================================
module BIN_TO_BCD_MODULE
#(
	parameter BIT_WIDTH=20,
	parameter BCD_WIDTH=24
)
(
	input	wClock,
	input	wReset,
	input	wEnable,
	
	input	wWE,
	input	[19:0]	BIN,
	output	[23:0]	BCD
);

function[3:0] LSA3;
	input [3:0] IN;
	case (IN)
		4'B0000: LSA3 = 4'B0000;
		4'B0001: LSA3 = 4'B0001;
		4'B0010: LSA3 = 4'B0010;
		4'B0011: LSA3 = 4'B0011;
		4'B0100: LSA3 = 4'B0100;
		4'B0101: LSA3 = 4'B1000;
		4'B0110: LSA3 = 4'B1001;
		4'B0111: LSA3 = 4'B1010;
		4'B1000: LSA3 = 4'B1011;
		4'B1001: LSA3 = 4'B1100;
		default: LSA3 = 4'B0000;
	endcase
endfunction

reg		[23:0]	rBCD;
reg		[23:0]	rBCD_OUT;
reg		[19:0]	rBIN;
reg		[4:0]	rBitCount;
reg		rBusy;
assign	BCD=rBCD_OUT;

wire	[23:0]	wBCD;
assign	wBCD={LSA3(rBCD[23:20]),LSA3(rBCD[19:16]),LSA3(rBCD[15:12]),LSA3(rBCD[11:8]),LSA3(rBCD[7:4]),LSA3(rBCD[3:0])};



always @(posedge wClock or negedge wReset)
	if(!wReset) begin
		rBCD_OUT	<=24'H000000;
		rBIN		<=20'H00000;
		rBitCount	<=5'D0;
		rBusy		<=1'B0;
	end
	else begin
		if(!rBusy) begin
			if(wWE) begin
				rBIN		<=BIN;
				rBusy		<=1'B1;
				rBitCount	<=5'D0;
				rBCD		<=24'H000000;
			end
		end
		else begin
			if(rBitCount==20) begin
				rBCD_OUT<=rBCD;
				rBusy<=1'B0;
			end
			else begin
				rBitCount	<=rBitCount+1'B1;
				{rBCD,rBIN}	<={wBCD[22:0],rBIN[19:0],1'B0};
			end
		end
	end

endmodule


 

该工程 从原来的 472个LE占用,优化大现在190个LE大笑

 

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值