自定义fifo接口控制器

自定义fifo接口控制器
目的:以自定义组件的形式添加到sopc中,用于nios ii读写fifo。
实现:verilog,读写分开设计。
一、fifo读写操作接口控制器的设计
1、fifo写操作接口控制器的设计
(1)采用基本写传输。
(2)有三个与fifo连接的信号
(3)data的位数可调,范围1~32bit之间。
(4)因为需要有参数可调,因此设计为一个top模块加上一个avalon模块的形式。
代码清单:
fifo_write_top.v代码如下
`timescale 1ps/1ps
/********************************************************
    说明:    1、该模块是自定义的fifo写操作控制器的顶层文件
            2、采用基本写传输,每次操作时仅维持一个时钟周期
            3、fifo数据格式可调,默认是16bit
            4、从设计时序上看,从端口收到write信号到fifo接收到数据
                间存在两个时钟周期
    作者:    tzj
    时间:    2011-09-30
    版本;    V1.0
    镭射打印
********************************************************/
module fifo_write_top
#(
    // parameters
    parameter bits_of_data = 16    // 可调参数
)
(
    // avalon clock interface signals
    input    clk,            // 总线时钟
    input reset_n,        // 总线复位
   
    // signals for avalon-mm slave port
    input chipselect,    // 片选
    input [ 1:0 ] address,        // 地址线
    input [ 3:0 ] byteenable,    // 数据字节使能
    input write,    // 写请求
metal dome    input [ 31:0 ] writedata,    // 写数据
   
    // fifo interface signals
    input full,        // fifo满标志
    output[ bits_of_data-1:0 ]    data,    // 写入fifo数据
    output wrreq    // fifo写请求
);
   
    defparam i1.bits_of_data = bits_of_data;    // 调整data位数
    fifo_write_avalon  i1(
        // avalon clock interface signals
        .clk( clk ),
        .reset_n( reset_n ),   
       
        // signals for avalon-mm slave port
        .chipselect( chipselect ),
        .address( address ),
        .byteenable( byteenable ),
        .write( write ),
        .writedata( writedata ),
       
        // fifo interface signals
        .data( data ),
        .full( full ),
        .wrreq( wrreq )
    );
endmodule
fifo_write_avalon.v代码如下
`timescale 1ps/1ps
/********************************************************
链轮设计
    说明:    1、该模块是自定义的fifo写操作控制器的核心文件
            2、avalon总线信号,每次操作时仅维持一个时钟周期
            3、fifo数据格式可调,默认是16bit
            4、从设计时序上看,从端口收到write信号到fifo接收到数据
                间存在两个时钟周期
    作者:    tzj
    时间:    2011-09-30
    版本:    V1.0
           
********************************************************/
module fifo_write_avalon (
                        // avalon clock interface signals
                        clk,
                        reset_n,                       
                        // signals for avalon-mm slave port
                        chipselect,
                        address,
                        byteenable,
                        write,
                        writedata,
                        // fifo interface signals
                        data,
                        full,
                        wrreq
                    );
    // parameters
    parameter bits_of_data = 16;    // 对应nios ii下可修改的参数
   
    //===============================================
    // 端口声明
    // avalon clock interface signals
    input    clk;            // 总线时钟
    input reset_n;        // 总线复位
   
    // signals for avalon-mm slave port
    input chipselect;    // 片选
    input [ 1:0 ] address;        // 地址线
    input [ 3:0 ] byteenable;    // 数据字节使能
    input write;    // 写请求
    input [ 31:0 ] writedata;    // 写数据
   
    // fifo interface signals
    input full;        // fifo满标志
    output[ bits_of_data-1:0 ]    data;    // 写入fifo数据
    output wrreq;    // 写fifo请求
    reg wrreq;
   
    //===============================================   
    // 寄存器
    reg [ 31:0 ] write_data_reg;    // 写数据寄存器
    reg write_data_reg_sel;    // 写数据寄存器使能
   
    //===============================================
    // 对控制寄存器地址进行译码
    always @ ( address )
        begin
            write_data_reg_sel <= 1'b0;
            case ( address )
                2'b00    :    write_data_reg_sel <= 1'b1;
                default:    write_data_reg_sel <= 1'b0;
            endcase
        end
    //===============================================       
    // 写入fifo数据寄存器
    always @ ( posedge clk or negedge reset_n )    // 上升沿时获取数据
        if ( !reset_n )
            write_data_reg = 32'b0;
        else if ( write & chipselect & write_data_reg_sel & !full )
            begin
                if ( byteenable[0] )
                    write_data_reg[ 7:0 ] = writedata[ 7:0 ];
                if ( byteenable[1] )
                    write_data_reg[ 15:8 ] = writedata[ 15:8 ];
                if ( byteenable[2] )
                    write_data_reg[ 23:16 ] = writedata[ 23:16 ];
                if ( byteenable[3] )
                    write_data_reg[ 31:24 ] = writedata[ 31:24 ];                   
            end
    //===============================================           
    // 写fifo请求
    always @ ( posedge clk or negedge reset_n )
        if ( !reset_n )
            wrreq = 1'b0;
        else if ( write & chipselect & write_data_reg_sel & !full )    // 非满
            wrreq = 1'b1;
        else
            wrreq = 1'b0;
    //===============================================           
    // 写数据   
    assign data = write_data_reg[bits_of_data-1:0];
   
endmodule
2、fifo读操作接口控制器的设计
采用带两个等待周期的读传输。
(1)采用带2个等待周期的读传输。
(2)有个与fifo连接的信号:
(3)q的位数可调,范围1~32bit之间;usedw的位数可调,根据fifo的usedw位数而设定
(4)因为需要有参数可调,因此设计为一个top模块加上一个avalon模块的形式。
代码清单:
fifo_read_top.v代码如下
`timescale 1ps/1ps
/********************************************************
    说明:    1、该模块是自定义的fifo读操作控制器
            2、avalon总线信号,每次操作时仅维持一个时钟周期
            3、读操作有两个时钟的等待
            4、状态读的是fifo的usedw,位数可调,默认6bit
            5、fifo外设的数据位数可调,默认16bit
    作者:    tzj & cj
    时间:    2011-09-30
    版本:    V1.0
   
********************************************************/
module fifo_read_top
#(
    // parameters
    parameter bits_of_q = 16,
    parameter bits_of_usedw = 6
)
(
    // avalon clk interface signals
    input clk,
    input reset_n,                       
    // signals for avalon-mm slave port
    input chipselect,
    input [1:0] address,
    input read,
    output [31:0] readdata,
    // fifo interface signals
    input [bits_of_q-1:0] q,
    input empty,
    input [bits_of_usedw-1:0] usedw,
    output rdreq
);
    defparam i1.bits_of_q = bits_of_q;
    defparam i1.bits_of_usedw = bits_of_usedw;
   
    fifo_read_avalon  i1(
        // avalon clk interface signals
        .clk( clk ),
        .reset_n( reset_n ),                       
        // signals for avalon-mm slave port
        .chipselect( chipselect ),
        .address( address ),
        .read( read ),
        .readdata( readdata ),
        // fifo interface signals
        .q( q ),
        .empty(empty),
        .usedw( usedw ),
        .rdreq( rdreq )
    );
endmodule
fifo_read_avalon.v代码如下
`timescale 1ps/1ps
/********************************************************
    说明:    1、该模块是自定义的fifo读操作控制器
            2、avalon总线信号,每次操作时仅维持一个时钟周期
            3、读操作有两个时钟的等待
            4、状态读的是fifo的usedw,位数可调,默认6bit
            5、fifo外设的数据位数可调,默认16bit
    作者:    tzj & cj
手提把    时间:    2011-09-30
    版本:    V1.0
   
********************************************************/
module fifo_read_avalon (
                        // avalon clk interface signals
                        clk,
                        reset_n,                       
                        // signals for avalon-mm slave port
                        chipselect,
                        address,
                        read,
                        readdata,
                        // fifo interface signals
                        q,
                        empty,
                        usedw,
                        rdreq
                    );
    // parameters
    parameter bits_of_q = 16;
    parameter bits_of_usedw = 6;
   
    //===============================================
    // 端口声明
    // avalon clk interface signals
    input    clk;            // 总线时钟
    input reset_n;        // 总线复位
   
    // signals for avalon-mm slave port
    input chipselect;    // 片选
    input [ 1:0 ] address;        // 地址线
    input read;        // 读请求
    output [ 31:0 ] readdata;    // 读数据
   
    // fifo interface signals
    input [ bits_of_q-1:0 ]    q;    // 读取fifo数据
    input    empty;    // fifo空标志
    input [bits_of_usedw-1:0] usedw;    // fifo使用情况
    output rdreq;    // 读fifo请求
   
    reg [ 31:0 ]    readdata;
    reg rdreq;
    reg wait_ready;        // 等待周期标志
    reg ready;    // 控制读的时钟标志
   
    //===============================================   
    // 寄存器
    wire [ 31:0 ]    read_data_reg;        // 读数据寄存器
    wire [ 31:0 ]    read_usedw_reg;    // 读状态寄存器
    reg read_data_reg_sel;    // 读数据寄存器使能
    reg read_usedw_reg_sel;// 读状态寄存器使能   
   
    //===============================================
    // 对控制寄存器地址进行译码,非阻塞
    always @ ( address )
        begin
            read_data_reg_sel    = 1'b0;
            read_usedw_reg_sel    = 1'b0;
            case ( address )
                2'b01    :    read_data_reg_sel = 1'b1;    // 使能读取数据寄存器
                2'b10    :    read_usedw_reg_sel = 1'b1;    // 使能读取状态寄存器
                default:   
                    begin
                    read_data_reg_sel = 1'b0;
                    read_usedw_reg_sel    = 1'b0;
                    end
            endcase
        end
    //===============================================
    // 读fifo请求
    always @ ( read or chipselect or read_data_reg_sel or empty or wait_ready or ready )
        begin
            rdreq = 1'b0;
            if ( read & chipselect & read_data_reg_sel & !empty & !wait_ready & !ready )    // rdreq信号只持续一个时钟,由wait_ready引起
                rdreq = 1'b1;
            else
                rdreq = 1'b0;
        end
   
    //===============================================
    // 控制时钟周期的标志
    always @ ( posedge clk or negedge reset_n )   
        if ( !reset_n )
            wait_ready <= 1'b0;
        else if ( read & chipselect & !wait_ready & !ready &(read_data_reg_sel | read_usedw_reg_sel))    // fifo收到rdreq的上升沿,即等待周期中
            wait_ready <= 1'b1;
        else if ( wait_ready )    // 第二个时钟上升沿,readdata将返回q值
胶衣树脂            wait_ready <= 1'b0;
        else
            wait_ready <= 1'b0;
    always @ ( posedge clk or negedge reset_n )   
        if ( !reset_n )
            ready <= 1'b0;
        else if ( wait_ready )    // fifo收到rdreq的上升沿,即等待周期中
            ready <= 1'b1;
        else
            ready <= 1'b0;
           
    //===============================================
    // 读取fifo寄存器数值       
    always @ ( posedge clk or negedge reset_n )
        if ( !reset_n )
            readdata = 32'h88888888;
        else if ( wait_ready )    // 等待一个时钟后返回结果标志
            case ( address )
                2'b01    :    readdata = read_data_reg;        // 返回数据值
                2'b10    :    readdata = read_usedw_reg;    // 返回空状态
                default:    readdata = 32'h88888888;
            endcase
    wire [32-bits_of_q-1:0] tmp1;
    wire [32-bits_of_usedw-1:0] tmp2;
    assign tmp1 = 0;
    assign tmp2 = 0;
   
    assign read_data_reg = { tmp1, q };    // 读入fifo输出的数据
    assign read_usedw_reg = { tmp2, usedw };    // 读fifo状态   
endmodule
二、添加该组件模块
1、将上述的代码清单,改为4个verilog文件。
2、建立一个工程,打开sopc builder。
3、在Component Library框下,选择“New”或者双击Project下的“New component”,会出现如下对话框:
4、添加源文件
进入“HDL Files”选项卡,通过“Add”添加源文件,注意将top文件指定为顶层文件,此处以读操作为例。
添加完以后,如下图:
5、设定信号
进入“Signals”选项卡,如下图:
修改与fifo连接的外部信号,按下图调整:
选择new Conduit,并将Signal Type设为export。
其余三个信号一样设置。
其余信号不需要调整。
调整完后,之前的error就消失了。
6、调整接口
进入“Interfaces”选项卡。
调整Timing这一项,把读等待设为两个周期。
Deprecated部分,小的选择的是动态。
把Conduit信号都改为实际的信号名,如下图:
7、可调参数
进入“HDL Parameters”选项卡,可以看到代码中所设定的两个可调的参数的位数。
8、库信息
进入“Library Info”选项卡,主要是修改Display name和所在的组Group。其余信息选填即可。如小的的是:
9、按照3~8的步骤,添加写操作接口控制器
需要注意的是,Timing保持默认即可,没有必要也把读等待改为两个周期。
10、添加ip路径
在工具栏“Tools”中选择“Options”,弹出:
选择Category中的Ip Search Path,通过Add把存放四个文件的文件夹路径指定。然后选中该路径,点击Finish。如果没有加载信息出现,则重复此过程即可。
11、至此,sopc下的自定义fifo读写接口控制器就添加完了。使用时,和altera提供的一样用,比如添加一个读控制器,如下图:
会出现parameters项,可以调节q的位数和usedw的位数。
三、问题及感谢
仅仅测试了8bit、16bit、24bit和32bit这四种情况。数据读取可以,一点小问题是,当把fifo写满,则此时读到的usedw信号显示为0而不是fifo的深度。不想想了,累死了。谁知道的话或者谁改过来了,可以告诉小的一下啊,不胜感谢!
圆珠笔尖
为了用这个,百度过谷歌过,貌似这个很简单,要不就是语焉不详,都没有看到详细代码,貌似csdn上有可惜是vhdl不懂。。。好在现在这个可以用了,将就凑活吧。小小抱怨一下:不喜欢csdn和pudn下个代码还要积分的,推崇免费。。。
新手菜鸟学习不容易,尤其英文还那么菜的,搞了好久才到这一步哎。高手们大虾们,似乎都不屑于解决这些小问题那。~~~~(>_<)~~~~高手们大侠们,路过不要喷小的。
如果大家有更好的fifo接口控制器,希望传给小的一份啊!
交流QQ:1771736249,注明百度文库,fpga哦

本文发布于:2024-09-22 15:38:06,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/1/249327.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:信号   可调   数据
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议