FPGA---------乒乓操作

1.乒乓操作原理

  乒乓操作是一个主要用于数据流控制的处理技巧,典型的乒乓操作如图所示:

FPGA---------乒乓操作_第1张图片

       外部输入数据流通过“输入数据选择控制”模块送入两个数据缓冲区中,数据缓冲模块可以为任何存储模块,比较常用的存储单元为双口RAM(Dual RAM),SRAM,SDRAM,FIFO等。

       在第1个缓冲周期,将输入的数据流缓存到“数据缓冲1”模块,在第2个缓冲周期,“输入数据选择控制”模块将输入的数据流缓存到“数据缓冲2”模块的同时,“输出数据选择控制”模块将“数据缓冲1”模块第一个周期缓存的数据流送到“后续处理”,模块进行后续的数据处理,在第三个缓冲周期,在“输入数据选择控制”模块的再次切换后,输入的数据流缓存到“数据缓冲1”模块,与此同时,“输出数据选择控制”模块也做出切换,将“数据缓冲2”模块缓存的第二个周期的数据送到“后续处理模块”,如此循环。

  正是利用了乒乓操作完成数据的无缝缓冲与处理,乒乓操作可以通过“输入数据选择控制”和“输出数据选择控制”按节拍,相互配合地进行来回切换,将经过缓冲的数据流没有停顿的送到“后续处理模块”。

2.乒乓操作源代码

module pingpong_operation(
    input clk,
    input rst,
    input [7:0] data_in,
    output reg [7:0] data_out
    );
reg [7:0] buffer_1;//缓存1
reg [7:0] buffer_2;//缓存2
reg wr_flag;//写标志,wr_flag=0,buffer_2写;wr_flag=1,buffer_1写
reg rd_flag;//读标志,rd_flag=0,buffer_1读;rd_flag=1,buffer_2读
reg state;// 状态机,1:写1读2,   0:写2读1,状态转移和输出分开编码

//状态转移
always@(posedge clk or negedge rst)
begin
    if (!rst)
        state<=0;
    else
        state<=~state;
end

//状态输出
always@(state)
begin
    case(state)
        0:
        begin
            wr_flag<=0;
            rd_flag<=0;
        end
        1:
        begin
            wr_flag<=1;
            rd_flag<=1;
        end
        default:
        begin
            wr_flag<=0;
            rd_flag<=0;
        end
    endcase
end

//写缓存buffer数据
always@(posedge clk or negedge rst)
begin
    if(!rst)
    begin
        buffer_1<=8'b0;
        buffer_2<=8'b0;
    end
    else
    begin
        case(wr_flag)
            0: buffer_2<=data_in;//wr_flag = 0,写buffer2
            1: buffer_1<=data_in;//wr_flag = 1,写buffer_1
            default:
            begin
                buffer_1<=0;
                buffer_2<=0;
            end
        endcase
    end
end
//读缓存buffer数据
always@(posedge clk or negedge rst)
begin
    if(!rst)
        data_out<=8'b0;
    else
        case(rd_flag)
            0:data_out<=buffer_1;
            1:data_out<=buffer_2;
            default:data_out<=0;
        endcase
end
endmodule

3.乒乓操作测试文件

`timescale 1ns / 1ps
module tb_pingpong_operation;
reg clk;
reg rst;
reg [7:0] data_in;
wire [7:0] data_out;
initial
begin
    clk<=0;
    rst<=0;
    #100 rst<=1;
end

always #10 clk<=~clk;

always@(posedge clk or negedge rst)
begin
    if(!rst)
        data_in<=0;
     else
        data_in<=data_in+1;
end

pingpong_operation u_pingpong(
    .clk(clk),
    .rst(rst),
    .data_in(data_in),
    .data_out(data_out)
    );
endmodule

4.仿真波形

FPGA---------乒乓操作_第2张图片

 

你可能感兴趣的:(FPGA经典设计)