前面进行了数码管的显示
对Avalon总线协议进行了大概的学习
那么就可以
将数码管译码器模块封装成符合Avalon-MM接口的组件
创建一个基于Nios Ⅱ处理器的系统
将数码管译码器组件添加至该系统中
通过用户应用程序控制数码管显示字符0~F
本实验基于Labcloud Intel FPGA实验平台
seg7_decoder_top.v
/*******************************************************************************
功能:
带有Avalon-MM接口的七段数码管译码器IP
接口:
avs_address: 七段数码管索引,如0指示第一个七段数码管,1指示第二个七段数码管
avs_write: 指示主机向该IP进行写传输
avs_writedata: 写入数据,并显示在七段数码管(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f)
avs_read: 指示主机向该IP进行读传输
avs_readdata: 读取七段数码管上显示的数据(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f)
参数:
SEG7_NUM:
七段数码管的个数,默认值为8
ADDR_WIDTH:
log2(SEG7_NUM),默认值为3
DEFAULT_VALUE:
复位后所有的七段数码管显示状态
1: 默认值,将所有七段数码管点亮,即显示8
0: 将所有七段数码管显示0
LOW_ACTIVE:
1: 共阳数码管,即低电平点亮数码管
0: 共阴数码管,即高电平点亮数码管
******************************************************************************/
module seg7_decoder_top #(
parameter SEG7_NUM = 8,
parameter ADDR_WIDTH = 3,
parameter DEFAULT_VALUE = 1,
parameter LOW_ACTIVE = 1
) (
//===== Avalon MM slave (read/write)接口
input clk, //时钟信号
input reset_n, //复位信号
input [(ADDR_WIDTH-1):0] avs_address, //Avalon Slave地址信号
input avs_write, //Avalon Slave写请求信号
input [7:0] avs_writedata, //Avalon Slave写数据
input avs_read, //Avalon Slave读请求信号
output reg [7:0] avs_readdata, //Avalon Slave读数据
//===== Avalon MM to export (conduit接口)
output [(SEG7_NUM*8-1):0] seg7 //驱动七段数码管显示的数据
);
// wires/regs变量声明
reg [7:0] reg_file [(SEG7_NUM-1):0];//定义了SEG7_NUM个八位寄存器,每个寄存器存储一个数码管上显示的字符
wire [(SEG7_NUM*8-1):0] dis_hex0to7;
// Avalon-MM slave 读写操作
always@(posedge clk) begin //复位,依次判断每个数码管的状态
if(~reset_n) begin
integer i;
for(i = 0; i < SEG7_NUM; i = i + 1) begin //将所有数码管都点亮,即所有数码管都显示“8”
reg_file[i] <= (DEFAULT_VALUE) ? 8'h8 : 8'h0;
end
end
else if(avs_write) //当写请求信号有效
reg_file[avs_address] <= avs_writedata; //进行写操作,Avalon MM Slave接口的写数据avs_writedata将回存储到地址为avs_address的寄存器中
else if(avs_read) //当读请求信号有效
avs_readdata <= reg_file[avs_address]; //进行读操作,会将地址为avs_address的寄存器中的数据读取值avs_readdata
end
// 七段数码管译码电路,写入数据avs_writedata为十六进制数字,需要进行译码才能驱动七段数码管电路
generate //使用generate-endgenerate减少代码重复
genvar m; //SEG7_NUM个七段数码管的译码电路
for(m = 0; m < SEG7_NUM; m = m + 1) begin: hex_decoder_x8
decod7seg hexm(
.hex (reg_file[m]), //译码器电路的输入为写入到寄存器reg_file中的数据
.display (dis_hex0to7[8*m+7:8*m]) //经过译码后输出驱动七段数码管电路
);
end
endgenerate
assign seg7 = (LOW_ACTIVE) ? dis_hex0to7 : ~dis_hex0to7; //判断是共阳数码管还是共阴数码管,然后驱动数码管
endmodule
decod7seg.v
module decod7seg (
input [3:0] hex,
output reg [6:0] display
);
/*
* 0
* ---
* | |
* 5| |1
* | 6 |
* ---
* | |
* 4| |2
* | |
* ---
* 3
*/
always @ (hex)
case (hex)
4'h0: display = 7'b1000000;
4'h1: display = 7'b1111001;
4'h2: display = 7'b0100100;
4'h3: display = 7'b0110000;
4'h4: display = 7'b0011001;
4'h5: display = 7'b0010010;
4'h6: display = 7'b0000010;
4'h7: display = 7'b1111000;
4'h8: display = 7'b0000000;
4'h9: display = 7'b0011000;
4'hA: display = 7'b0001000;
4'hB: display = 7'b0000011;
4'hC: display = 7'b1000110;
4'hD: display = 7'b0100001;
4'hE: display = 7'b0000110;
4'hF: display = 7'b0001110;
endcase
endmodule
Platform Designer是Nios Ⅱ软核处理器的开发工具,用于实现Nios Ⅱ系统配置、生成以及Nios Ⅱ系统相关的监控和软件调试平台的生成
(1)首先打开Quartus工具栏Tool->Platform Designer,选择左上角New Component,打开Component工具填写组件信息
(2)组件信息填写完后,点Files->Add File,选中seg7_decoder_top.v和decod7seg.v,将其添加到Synthesis Files中
点击 seg7_decoder_top.v文件的no attributes,选中弹出窗口中的Top-level File,将其设为顶层文件,然后点击Analyze Synthesis Files分析综合
可以看到在跳出的提示框中显示成功(如果有错说明添加的Verilog文件有错误,如语法错误)
但完成分析综合后的Messages窗口会报错,这是因为有一些参数没有设置
首先在Parameters中确保定能Verilog模块中声明的四个参数都Editable都是勾选的
在Signals & Interfaces中,左侧的Name栏显示的是分析综合时,根据信号名自动对信号进行了分组,但这样的分组不一定正确,因此要逐一设置
首先设置clk和reset_n
点击avalon_slave_0,将Associated Clock设置为clock, Associated Reset设置为reset
然后依次设置ava_adderess、ava_read、ava_write、ava_writedata
然后右键点击seg7[64],选择remove,报错全部解决
然后点击add interface,选择conduit
最后点击下面的finish并保存,seg7_decoder组件创建完毕,可以在Platform Designer中看到创建的组件