fifo 一个16bit转化为两个8bit

项目中用到将位宽16bit转化为两个8bit,今日刚有空做了个整理。

项目中将ddr数据突发读到一个位宽为16bit的fifo,而w5500写入数据位宽为8bit,这里需要做个转化,用了二级fifo形式。源代码如下

/*-------------------------------------------------------------------------
Filename               :        fifo_two_level.v
Author                   :        lei
Data                   :        2020-1-7
Version                   :        1.0
Description               :        将16bit的fifo缓存转化为8bit的fifo缓存
Modification History   :
Data            By            Version            Change Description        
===========================================================================
20/01/02        lei            v1.2           将一个16bit转化两个8bit        
--------------------------------------------------------------------------*/
module fifo_two_level
(
  input                    clk                 ,    
  input                    rst_n               ,
  input                 wr_en               ,
  input  [15:0]         wr_data             ,
  input                 rd_en_2             ,  //读使能
  output                rdreq_2             ,  //请求读出
  output [7:0]          rd_data_2              //读出位宽为8bit数据
);
reg             cnt_en             ;
wire            add_cnt            ;
wire            end_cnt            ;
wire      [9:0] usedw_sig_1        ; //第一级缓存空间大小
wire            rdreq_fifo_1       ; //一级缓存空间有数据,请求读出
wire            rd_en_1            ; //一级缓存读使能
wire            wrreq_fifo2        ; //二级缓存空间有空间,请求写入
wire     [15:0]  data_out_1        ; //一级缓存读出数据,类型16bit
reg      [7:0]   wr_data_2         ; //二级缓存读入数据,类型8bit
reg      [3:0]  cnt                ; //计数
reg             wr_en_2            ; //二级缓存写入使能

  

assign    add_cnt =cnt_en     ;
assign    end_cnt = add_cnt && cnt == 4'd5-4'd1;
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        cnt_en<=1'b0;  
    else if(end_cnt)
        cnt_en<=1'b0;
    else if(wrreq_fifo2 &&rdreq_fifo_1)     //进行转化的起始信号
        cnt_en<=1'b1;    
    else
        cnt_en<=cnt_en;    
end
always @(posedge clk or negedge rst_n)begin
      if(rst_n==1'd0)begin
          cnt <= 4'd0;
      end
      else if(add_cnt)begin
          if(end_cnt)begin
             cnt <= 4'd0;
          end
          else
             cnt <= cnt + 1'b1;
      end
end
assign rd_en_1=cnt==4'd1;  //在计数1读使能,在2读到数,在3取读到数低8位,在4取高8位;
assign rdreq_fifo_1=usedw_sig_1>=10'd1;

  
fifo_2k_16bit    fifo_2k_16bit (
.aclr ( ~rst_n        ),
.clock( clk          ),
.data ( wr_data           ),
.rdreq( rd_en_1           ),
.wrreq(wr_en              ),
.q    ( data_out_1        ),
.usedw( usedw_sig_1       )
);

always @(posedge clk or negedge rst_n)begin
    if(rst_n==1'd0)begin
        wr_en_2  <=1'b0  ;
        wr_data_2<=8'd0  ;
    end
    else if(cnt==4'd3)begin
        wr_en_2  <=1'b1  ;
        wr_data_2<=data_out_1[7:0];
    end
    else if(cnt==4'd4)begin
        wr_en_2  <=1'b1  ;
        wr_data_2<=data_out_1[15:8];
    end
    else begin
        wr_en_2  <=1'b0  ;
        wr_data_2<=wr_data_2;
    end
end

wire   [7:0]  usedw_sig_2  ;
assign wrreq_fifo2=usedw_sig_2<=8'd200;
assign rdreq_2    =usedw_sig_2>=8'd1;
fifo256    fifo256_inst_t (       //写入和写出数据时8位的,用于相关控制命令
    .aclr ( ~rst_n ),
    .clock ( clk  ),
    .wrreq ( wr_en_2 ),
    .data ( wr_data_2 ),
    .rdreq ( rdreq_2 ),    
    .usedw (usedw_sig_2   ),    //有数据时为低电平
    .q ( rd_data_2 )
);
endmodule

fifo 一个16bit转化为两个8bit