FPGA服务器硬件搭建涉及的知识点4

七段数码管ip核定制:

下面分析一下友晶提供的七段数码管的avalon接口驱动代码

module SEG7_IF(	
					//===== avalon MM s1 slave (read/write)
					// write
					s_clk,
					s_address,
					s_read,
					s_readdata,
					s_write,
					s_writedata,
					s_reset,
					//

					//===== avalon MM s1 to export (read)
					// read/write
					SEG7
				 );
				
/*****************************************************************************
 *                           Parameter Declarations                          *
 *****************************************************************************/
parameter	SEG7_NUM		=   8;
parameter	ADDR_WIDTH		=	3;		
parameter	DEFAULT_ACTIVE  =   1;
parameter	LOW_ACTIVE  	=   1;

//`define 	SEG7_NUM		   8
//`define		ADDR_WIDTH		   3		
//`define		DEFAULT_ACTIVE     1
//`define		LOW_ACTIVE  	   1




/*****************************************************************************
 *                             Internal Wire/Register                         *
 *****************************************************************************/

reg		[7:0]				base_index;
reg		[7:0]				write_data;
reg		[7:0]				read_data;
reg		[(SEG7_NUM*8-1):0]  reg_file;



/*****************************************************************************
 *                             Port Declarations                             *
 *****************************************************************************/
 // s1
input						s_clk;
input	[(ADDR_WIDTH-1):0]	s_address;
input						s_read;
output	[7:0]				s_readdata;
input						s_write;
input	[7:0]				s_writedata;
input						s_reset;


//===== Interface to export
 // s1
output	[(SEG7_NUM*8-1):0]  SEG7;




/*****************************************************************************
 *                            Sequence logic                                  *
 *****************************************************************************/
 
always @ (negedge s_clk)
begin
	
	if (s_reset)
	begin
		integer i;
		for(i=0;i<SEG7_NUM*8;i=i+1)
		begin
			reg_file[i] = (DEFAULT_ACTIVE)?1'b1:1'b0; // trun on or off 
		end
	end
	else if (s_write)
	begin
		integer j;
		write_data = s_writedata;
		base_index = s_address;
		base_index = base_index << 3;
		for(j=0;j<8;j=j+1)
		begin
			reg_file[base_index+j] = write_data[j];
		end
	end
	else if (s_read)
	begin
		integer k;
		base_index = s_address;
		base_index = base_index << 3;
		for(k=0;k<8;k=k+1)
		begin
			read_data[k] = reg_file[base_index+k];
		end
	end	
end
 


/*****************************************************************************
 *                            Combinational logic                            *
 *****************************************************************************/
assign SEG7 = (LOW_ACTIVE)?~reg_file:reg_file;
assign s_readdata = read_data;


endmodule
这里定义的驱动信号并没有按照avalon总线协议规定的信号类型来写,在添加ip核的时候要按照avalon协议

给每个驱动信号分配信号类型。

reg		[(SEG7_NUM*8-1):0]  reg_file;这一行代码有点费解,定义这64个reg_file干嘛(SEG7_NUM=8),

查看原理图晓得,板子上共8个数码管,共64段,每段由芯片的一个io口控制,reg_file表示64个io寄存器文件,

用来管理8个数码管的共64个io口。

查看板子的原理图发现并没有什么位选和段选,64个段一字排开各连各的io口,在以前用51的时候都会有8个io口

用做位选,那这里没有位选信号那怎么选择需要点亮的数码管呢?

玄机在下面的代码:

begin
		integer j;
		write_data = s_writedata;
		base_index = s_address;
		base_index = base_index << 3;
		for(j=0;j<8;j=j+1)
		begin
			reg_file[base_index+j] = write_data[j];
		end
	end
base_index << 3;地址左移3位,就相当于跨过一整个数码管的8个段,来到下一个数码管的第一个段,
然后代码:reg_file[base_index+j] = write_data[j];就开始向下一个数码管的8个段的每个段写入数据。
总结一下:每次左移8位即跳过一个数码管的8个io口到下一个数码管的第一位,没有专门的位选信号,一次性
左移8个io口就相当于位选了。它是</span><span s用这种方式来实现位选的功能。
用什么方式来选择数码管那要看具体的电路图是怎么设计的.


posted @ 2015-11-29 10:47  王纯配  阅读(112)  评论(0编辑  收藏  举报