基于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中

原文地址:https://www.cnblogs.com/wen2376/p/15731987.html