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用这种方式来实现位选的功能。
用什么方式来选择数码管那要看具体的电路图是怎么设计的.