使用两个FIFO完成流水操作

软件发布|下载排行|最新软件

当前位置:首页IT学院IT技术

使用两个FIFO完成流水操作

橘子哥哥hym   2021-02-02 我要评论

一、设计目标

     写一个FIFO控制器,控制器里有两个FIFO,输入的数据由串行接收模块(uart_rx_module)送来,一共有86行86列的数据,按0、1、2行,1、2、3行,直到最后83、84、85行,每3行为一组进行加操作,即每一组的每一列三个数进行相加,每一组要加86次。传过来的第一行数据先暂存在FIFO1中,第二行数据先暂存在FIFO2中,从第三行数据开始流水操作,即取出第一、二行的数据,与输入的新数据相加,将结果通过串行发送模块(uart_tx_module)发送出去,在相加的同时,将新数据存在FIFO2中,将FIFO2中读出的数据重新存在FIFO1中,这一组的加操作完成后,FIFO1中为第1行的数据,FIFO2中为第二行的数据,以此操作不断循环,直到最后一组。

二、设计思路

2.1 设计先知 

  1. 串口传输过来的86×86的数据是每十个波特时间才传输一次,每一个数据传送过来的同时会有标志位拉高,只需要判断该标志位即可进行读写操作。
  2. 因为是三行数据相加,所以先要把前两行的数据先存到fifo1和fifo2,当第三行数据传输过来的时候,再把三个数据(两个fifo输出端和rx输出)相加。
  3. 第0、1、2行加完后,需要把第1、2、3行数据相加,这时第0、1、2行的数据已经全部读出来了,所以需要在相加的时候把后面两行(第1、2行)数据存到fifo里面,即相加的同时需要将fifo2的数据存入fifo1,pi_data的数据存入fifo2。
  4. 最后三行相加,即第83、84、85行相加,不需要写数据了,写使能可以关闭了,只需要读使能,将fifo1里面的83行读出来和将fifo2里面的84行读出来,然后与新传送过来的85行进行相加。

 

2.2 设计结构图

 

 

 

 

2.3 fifo核的读写时序

 

 

 

 

 

2.4 fifo控制模块的时序图

 

 

接口传输方向

接口名称

位宽

功能

输入

Pi_flag

1

输入数据有效标志位,为高代表有数据输入

输入

Pi_data

8

输入的一个8位数据

中间变量

Cnt_col

8

列计数器,用于统计每一行写入的数据个数

中间变量

Cnt_row

8

行计数器,用于统计输入数据的行数

中间变量

Wr_en_1

1

Fifo1的写使能,控制fifo数据的写入

中间变量

Wr_en_2

1

Fifo2的写使能,控制fifo数据的写入

中间变量

Data_in_1

8

Fifo1写入数据的端口

中间变量

Data_in_2

8

Fifo2写入数据的端口

中间变量

Data_out_1

8

Fifo1读出数据的端口

中间变量

Data_out_2

8

Fifo2读出数据的端口

中间变量

Rd_en

1

Fifo1和Fifo2读使能,控制两个Fifo数据的读出

中间变量

Flag_add

1

加操作使能信号,为高时控制三个数据相加

输出

Po_sum

8

存放每一组,每列三个数据相加的结果

输出

Po_flag

1

输出数据有效标志位

 

 

 

 

三、关键代码

3.1串口接受模块

module uart_rx_moudule(
    input      wire       Clk,
    input      wire       Rst_n,
    input      wire       rx,
    output     reg        po_flag,
    output     reg  [7:0] po_data
);

wire Rst;
assign Rst=~Rst_n;
   
reg          rx1;
reg          rx2;
reg          rx2_reg;
reg [12:0]   cnt_baud;
parameter    CNT_BAUD_MAX = 13'd5207;
parameter    HALF_CNT_BAUD_MAX = 13'd2603;
reg          rx_flag;
reg [3:0]    bit_cnt;
reg          bit_flag;
//打第一拍   
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin
      rx1<=1'd0;
      end
   else 
        begin
        rx1<=rx;
        end
//打第二拍
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin
      rx2<=1'd0;
      end
   else 
        begin
        rx2<=rx1;
        end
//打第三拍
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin
      rx2_reg<=1'd0;
      end
   else 
        begin
        rx2_reg<=rx2;
        end
//rx_flag
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin
      rx_flag<=1'b0;
      end
   else if((!rx2)&&(rx2_reg))
        begin
        rx_flag<=1'b1;
        end
   else if((bit_cnt=='d8)&&(bit_flag))
        begin
        rx_flag<=1'b0;  
        end
//cnt_baud
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin
      cnt_baud<='d0;
      end
   else if((cnt_baud==CNT_BAUD_MAX)||(!rx_flag))
        begin
        cnt_baud<='d0;
        end
   else 
        begin
        cnt_baud<=cnt_baud+1'b1;
        end
//bit_flag
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin
      bit_flag<=1'b0;
      end
   else if(cnt_baud==HALF_CNT_BAUD_MAX)
        begin
        bit_flag<=1'b1;
        end
   else 
        begin
        bit_flag<=1'b0;
        end
//bit_cnt
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin
      bit_cnt<='b0;
      end
   else if((bit_cnt=='d8)&&(bit_flag))
        begin
        bit_cnt<='b0;
        end
   else if(bit_flag)
        begin
        bit_cnt<=bit_cnt+1'b1;
        end
//po_data
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin
      po_data<='d0;
      end
   else if((bit_flag)&&(bit_cnt>='d1))
        begin
        po_data[bit_cnt-1'b1]<=rx2;
        end
//po_flag
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin
      po_flag<=1'b0;
      end
   else if((bit_flag)&&(bit_cnt=='d8))
        begin
        po_flag<=1'b1;
        end
   else 
        begin
        po_flag<=1'b0;
        end
endmodule

 

 

 

 

 3.2串口发送模块

module uart_tx_module(
    input    wire         Clk,
    input    wire         Rst_n,
    input    wire [7:0]   pi_data,
    input    wire         pi_flag,
    output   reg          tx
);

wire Rst;
assign Rst=~Rst_n;

reg [7:0]  data_temp;//数据暂存
reg        tx_flag;//控制发送定时器
reg [3:0]  bit_cnt;//控制发送位数
reg        bit_flag;
reg [12:0] cnt_baud;
parameter  CNT_BAUD_MAX = 13'd5207;

//data_temp
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin
      data_temp<='d0; 
      end
   else if(pi_flag)
        begin
        data_temp<=pi_data;
        end
//tx_flag
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin
      tx_flag<=1'b0;
      end
   else if(pi_flag)
        begin
        tx_flag<=1'b1;
        end
   else if((bit_cnt=='d8)&&(bit_flag))
        begin
        tx_flag<=1'b0;
        end

//cnt_baud
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin
      cnt_baud<='d0;
      end
   else if((cnt_baud==CNT_BAUD_MAX)||(!tx_flag))
        begin
        cnt_baud<='d0;
        end
   else 
        begin
        cnt_baud<=cnt_baud+1'b1; 
        end

//bit_flag
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin   
      bit_flag<=1'b0;
      end
   else if(cnt_baud==CNT_BAUD_MAX-1'b1)
        begin
        bit_flag<=1'b1;
        end
   else 
        begin
        bit_flag<=1'b0;
        end
//bit_cnt
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin
      bit_cnt<='d0;
      end
   else if((bit_cnt=='d8)&&(bit_flag))
        begin
        bit_cnt<='d0;
        end
   else if(bit_flag)
        begin
        bit_cnt<=bit_cnt+1'b1;
        end

//tx
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin
      tx<='d1;
      end
   else if(pi_flag)
        begin
        tx<=1'b0;  
        end
   else if((bit_flag)&&(bit_cnt<='d7))
        begin
        tx<=data_temp[bit_cnt]; 
        end
   else if((bit_flag)&&(bit_cnt=='d8))
        begin
        tx<=1'b1;
        end
endmodule

 3.3 fifo控制模块

//=============================================================
// ---名 称:fifo_ctrl
// ---作 者:橘子哥哥
// ---Q  Q :1073273114
// ---we chat:15870894502
// ---日 期:2021-1-31
// ---描 述:控制两个fifo核完成读写流水操作
//=============================================================
module fifo_ctrl(
    input      wire        Clk,
    input      wire        Rst_n,
    input      wire        pi_flag,
    input      wire [7:0]  pi_data,
    output     reg         po_flag,
    output     reg  [7:0]  po_sum
);
wire Rst;
assign Rst=~Rst_n;

reg  [7:0]cnt_col;
reg  [7:0]cnt_row;
reg       wr_en_1;
reg       wr_en_2;
reg       rd_en;
wire [7:0]data_in_1;
wire [7:0]data_in_2;
wire [7:0]data_out_1;
wire [7:0]data_out_2;
reg       flag_add;
//cnt_col
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin
      cnt_col<='d0;
      end
   else if((cnt_col=='d85)&&(pi_flag))
        begin
        cnt_col<='d0;
        end
   else if(pi_flag)
        begin
        cnt_col<=cnt_col+1'b1;
        end
//cnt_row
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin
      cnt_row<='d0;
      end
   else if((cnt_col=='d85)&&(cnt_row=='d85)&&(pi_flag))
        begin
        cnt_row<='d0;
        end
   else if((cnt_col=='d85)&&(pi_flag))
        begin
        cnt_row<=cnt_row+1'b1;
        end
//wr_en_1
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin
      wr_en_1<=1'd0;
      end
   else if(((pi_flag)&&(cnt_row=='d0))||((cnt_row>='d2)&&(cnt_row<='d84)&&(rd_en))||((cnt_row=='d85)&&(cnt_col=='d0)&&(rd_en)))
        begin
        wr_en_1<=1'b1;
        end
   else 
        begin
        wr_en_1<=1'b0;
        end
//wr_en_2
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin  
      wr_en_2<=1'b0;
      end
   else if(((pi_flag)&&(cnt_row=='d1))||((cnt_row>='d2)&&(cnt_row<='d84)&&(rd_en))||((cnt_row=='d85)&&(cnt_col=='d0)&&(rd_en)))
        begin
        wr_en_2<=1'b1;
        end
   else 
        begin
        wr_en_2<=1'b0;
        end
//rd_en
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin
      rd_en<=1'b0;
      end
   else if((cnt_row>='d2)&&(cnt_row<='d85)&&(pi_flag))
        begin
        rd_en<=1'b1;
        end
   else
        begin
        rd_en<=1'b0;
        end
//flag_add
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin
      flag_add<=1'b0;
      end
   else if(rd_en)
        begin
        flag_add<=1'b1;
        end
   else 
        begin
        flag_add<=1'b0;
        end
//po_sum
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin
      po_sum<='d0;
      end
   else if(flag_add)
        begin
        po_sum<=data_out_1+data_out_2+pi_data;
        end
//po_flag
always@(posedge Clk or posedge Rst)
   if(Rst)
      begin
      po_flag<='d0;
      end
   else if(flag_add)
        begin
        po_flag<='d1;
        end
   else
        begin
        po_flag<='d0;
        end
//data_in_1
assign data_in_1=(cnt_row<='d1)?pi_data:data_out_2;
//data_in2
assign data_in_2=pi_data;

fifo fifo_inst1(
  .wr_clk(Clk), // input wr_clk
  .rd_clk(Clk), // input rd_clk
  .din(data_in_1), // input [7 : 0] din
  .wr_en(wr_en_1), // input wr_en
  .rd_en(rd_en), // input rd_en
  .dout(data_out_1), // output [7 : 0] dout
  .full(), // output full
  .empty() // output empty
);
fifo fifo_inst2 (
  .wr_clk(Clk), // input wr_clk
  .rd_clk(Clk), // input rd_clk
  .din(data_in_2), // input [7 : 0] din
  .wr_en(wr_en_2), // input wr_en
  .rd_en(rd_en), // input rd_en
  .dout(data_out_2), // output [7 : 0] dout
  .full(), // output full
  .empty() // output empty
);
endmodule

3.4顶层模块

//=============================================================
// ---名 称:top_double_fifo
// ---作 者:橘子哥哥
// ---Q  Q :1073273114
// ---we chat:15870894502
// ---日 期:2021-1-31
// ---描 述:双流水fifo顶层模块
//=============================================================
module top_double_fifo(
    input     wire    Clk,
    input     wire    Rst_n,
    input     wire    rx,
    output    wire    tx
);
wire       flag1,flag2;
wire [7:0] data1,data2;
uart_rx_moudule uart_rx_moudule_inst(
    .Clk(Clk),
    .Rst_n(Rst_n),
    .rx(rx),
    .po_data(data1),
    .po_flag(flag1)
    );
fifo_ctrl fifo_ctrl_inst(
    .Clk(Clk),
    .Rst_n(Rst_n),
    .pi_flag(flag1),
    .pi_data(data1),
    .po_flag(flag2),
    .po_sum(data2)
);
uart_tx_module uart_tx_module_inst(
    .Clk(Clk),
    .Rst_n(Rst_n),
    .pi_flag(flag2),
    .pi_data(data2),
    .tx(tx)
    );

endmodule

 

Copyright 2022 版权所有 软件发布 访问手机版

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们