• 基于FIFO实验仿真测试 输入数据是8位宽,FIFO位宽是16位,练习思路


    设计要求:上游模块产生的数据是8位宽, FIFO输入输出而是16位宽的,那么就需要将上游产生的两个8bit数据进行拼接,凑成一个完整的16bit数据,然后再一次写入fifo

    上游模块产生两个信号    datat_in[7:0] 和 data_in_vld 给FIFO,在控制FIFO模块中,将利用这两个信号通过一定方式转换成写入FIFO,思路步骤如下:

    (1)、将两个8bit数据拼接一个16bit的,那么就需要一个计数器 (cnt0),对数据进行数数,数两个,所以位宽1bit就够 ,定义

    reg [0:0] cnt0;

    (2)、计数器启动条件 (add_cnt0), 启动条件无非就是利用data_in_vld ,当data_in_vld 有效时,立刻启动计数器,可以画出data_in_vld 和 add_cnt0的波形对应关系了

    add_cnt0 = data_in_vld  == 1;

    (3)、计数器结束条件(end_cnt0),当计数器cnt0 == 2-1 时(也就是数到了2个数),就停止计数。  根据cnt0 数数情况,可以画出end_cnt0的波形了

    end_cnt0 = add_cnt0 && cnt0 == 2-1;

    (4)、该考虑处理怎么处理data_in的数据了,肯定要结合 cnt0 将 数据 进行 拼接,在cnt0 == 1-1 时,就得将第一个data_in[7:0]的数据保存到data_temp[15:8]中的高八位,

        在cnt0 == 2-1 时,就得将 data_in[7:0]的数据保存到data_temp[7:0]中的低八位。如下写法

     1 always @(posedge clk_in or negedge rst_n)begin
     2     if(!rst_n)begin
     3         data_temp <= 0;
     4     end
     5     else if(add_cnt0 && cnt0 == 1)begin
     6         data_temp[7:0] <= data_in;
     7     end
     8     else if(add_cnt0 && cnt0 == 0)begin
     9         data_temp[15:8] <= data_in;
    10     end
    11 end

    可以将上面的形式转换另外一种高级方式:

    always @(posedge clk_in or negedge rst_n)begin
        if(!rst_n)begin
            data_temp <= 0;
        end
        else if(add_cnt0 && cnt0 >= 0 && cnt0 < 2)begin
            data_temp[DOUT_W-1 - cnt0*DIN_W -:DIN_W] = data_in;
        end
    end
    data_temp[DOUT_W-1 - cnt0*DIN_W -:DIN_W] = data_temp[16-1 - cnt0*8 -:8]:

    当cnt0 = 0 时,data_temp[16-1 - 0*8 -:8] = data_temp[15 -:8] 表示data_temp第15位开始,往下数8个,相当于就是datat_temp[15:8]
    当cnt0 = 1 时,data_temp[16-1 - 1*8 -:8] = data_temp[7 -:8] 表示data_temp第7位开始,往下数8个,相当于就是datat_temp[7:0]

    是不是立马觉得很高级了,一行表示完,看起来代码少了,但理解起来有点费劲,就让人产生高级感了!!!!

    根据cnt0,就可以画出data_temp 和cnt0的对应关系了。

    (4)、拼接完了,那就得考虑如何产生wrreq信号了,首先记住一个关键点,wrreq 和待写入fifo的数据(data_temp[15:0])要保持在同一拍,既然要保持在同一拍,说明数据拼接好了

     就可以画出 wrreq 和 data_temp[15:0] 的波形,如下图,

     wrreq 和 data_temp = 16'h1011 保持在同一拍,且wrreq只能保持一个时钟周期,画出这两个相对应的波形。

    现在波形画的差不多了,可以看出在哪个节点 将 wrreq 拉高,也就是end_cnt0 == 1 时,将wrreq拉高,因为还要考虑一个usedw条件,所以将两个条件一同写上,如下代码:
    always @(posedge clk_in or negedge rst_n)begin
        if(!rst_n)begin
            wrreq <= 0;
        end
        else if(end_cnt0 && wrusedw < 61 )begin  
            wrreq <= 1;            //只保留一个时钟周期
        end
        else begin
            wrreq <= 0;
        end
    end

    大概轮廓波形:

    modelsim仿真波形:  在wrreq = 1  期间, data_temp = 16'h1011, 保持在同一拍,且只保留一个时钟周期,当第一个写完之后,可以看到q 上面已经显示 16'h1011,说明已成功写入fifo中

  • 相关阅读:
    JS判断鼠标从什么方向进入一个容器
    [JS进阶] 编写可维护性代码 (1)
    CSS3 animation小动画
    如何使用js捕获css3动画
    webpack入门(译)
    js拖拽3D立方体旋转
    简单3D翻转
    html 基础
    python 并发编程
    python 网络编程
  • 原文地址:https://www.cnblogs.com/wen2376/p/15731987.html
Copyright © 2020-2023  润新知