自定义seg_decoder组件并创建Nios系统(一)

前面进行了数码管的显示
对Avalon总线协议进行了大概的学习


那么就可以

将数码管译码器模块封装成符合Avalon-MM接口的组件
创建一个基于Nios Ⅱ处理器的系统

将数码管译码器组件添加至该系统中

通过用户应用程序控制数码管显示字符0~F

本实验基于Labcloud Intel FPGA实验平台

1. 自定义seg_decoder组件

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

 2.Platform Designer创建组件

Platform Designer是Nios Ⅱ软核处理器的开发工具,用于实现Nios Ⅱ系统配置、生成以及Nios Ⅱ系统相关的监控和软件调试平台的生成

(1)首先打开Quartus工具栏Tool->Platform Designer,选择左上角New Component,打开Component工具填写组件信息

自定义seg_decoder组件并创建Nios系统(一)_第1张图片

自定义seg_decoder组件并创建Nios系统(一)_第2张图片

(2)组件信息填写完后,点Files->Add File,选中seg7_decoder_top.v和decod7seg.v,将其添加到Synthesis Files中

自定义seg_decoder组件并创建Nios系统(一)_第3张图片

点击 seg7_decoder_top.v文件的no attributes,选中弹出窗口中的Top-level File,将其设为顶层文件,然后点击Analyze Synthesis Files分析综合

自定义seg_decoder组件并创建Nios系统(一)_第4张图片

 可以看到在跳出的提示框中显示成功(如果有错说明添加的Verilog文件有错误,如语法错误)

但完成分析综合后的Messages窗口会报错,这是因为有一些参数没有设置自定义seg_decoder组件并创建Nios系统(一)_第5张图片

 首先在Parameters中确保定能Verilog模块中声明的四个参数都Editable都是勾选的

自定义seg_decoder组件并创建Nios系统(一)_第6张图片

在Signals & Interfaces中,左侧的Name栏显示的是分析综合时,根据信号名自动对信号进行了分组,但这样的分组不一定正确,因此要逐一设置

首先设置clk和reset_n

自定义seg_decoder组件并创建Nios系统(一)_第7张图片自定义seg_decoder组件并创建Nios系统(一)_第8张图片 点击avalon_slave_0,将Associated Clock设置为clock, Associated Reset设置为reset 

自定义seg_decoder组件并创建Nios系统(一)_第9张图片

 然后依次设置ava_adderess、ava_read、ava_write、ava_writedata

自定义seg_decoder组件并创建Nios系统(一)_第10张图片

自定义seg_decoder组件并创建Nios系统(一)_第11张图片

自定义seg_decoder组件并创建Nios系统(一)_第12张图片

自定义seg_decoder组件并创建Nios系统(一)_第13张图片自定义seg_decoder组件并创建Nios系统(一)_第14张图片 然后右键点击seg7[64],选择remove,报错全部解决

自定义seg_decoder组件并创建Nios系统(一)_第15张图片

然后点击add interface,选择conduit

 自定义seg_decoder组件并创建Nios系统(一)_第16张图片

自定义seg_decoder组件并创建Nios系统(一)_第17张图片

自定义seg_decoder组件并创建Nios系统(一)_第18张图片 最后点击下面的finish并保存,seg7_decoder组件创建完毕,可以在Platform Designer中看到创建的组件

你可能感兴趣的:(一般人学不会的FPGA,fpga开发,嵌入式硬件)