乒乓buffer操作

部分为转载

速度和面积问题:

速度:能达到的最高时钟频率,与建立保持时间和外部器件的时序,以及紧密逻辑关系的寄存器的逻辑时延、走线时延有关.

面积:所消耗的触发器FF、查找表LUT等逻辑资源

例子:串——并转换

串行输入数据,经过n个移位寄存器,并行输出。就是拿面积换取速度。

乒乓操作,输入数据选择控制为A,输出数据选择控制为B
        在第1个缓冲周期,将输入的数据流缓存到A
        在第2个缓冲周期,A模块将输入的数据流缓存到B模块的同时,B模块将“数据缓冲1”模块第一个周期缓存的数据流送到“后续处理”,模块进行后续的数据处理,
        在第3个缓冲周期,在A模块的再次切换后,输入的数据流缓存到“数据缓冲1”模块,与此同时,B模块也做出切换,将“数据缓冲2”模块缓存的第二个周期的数据送到“后续处理模块”,如此循环。
优点、1、乒乓操作完成数据的无缝缓冲与处理:通过“输入数据选择控制”和“输出数据选择控制”按节拍,相互配合地进行来回切换,将经过缓冲的数据流没有停顿的送到“后续处理模块”

//wr_flag  rd_flag c_state
     // 0          0        0
     // 1          1        1

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date:    16:39:16 12/31/2021 
// Design Name: 
// Module Name:    pingpang 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//
module pingpang
    (
        input            clk        ,
        input            rst_n      ,
        input      [7:0] data_in    ,  // 输入数据
        output reg [7:0] data_out   ,  // 输出数据
		  output reg [7:0] buffer1    ,  // 缓存1
        output reg [7:0] buffer2    ,  // 缓存2 
		  output reg       wr_flag    ,  // 写标志,wr_flag=0,写buffer1,wr_flag=1,写buffer2
        output reg       rd_flag       // 读标志,rd_flag=0,读buffer2,rd_flag=1,读buffer1		  
    );

// ------------------------------------------------------ //
	 //wr_flag  rd_flag c_state
	 // 0          0        0
     // 1          1        1
    //reg [7:0]    buffer1    ;    // 缓存1
    //reg [7:0]    buffer2    ;    // 缓存2
    //reg          wr_flag    ;    // 写标志,wr_flag=0,写buffer1,wr_flag=1,写buffer2
    //reg          rd_flag    ;    // 读标志,rd_flag=0,读buffer2,rd_flag=1,读buffer1
    reg          c_state    ;    // 状态机,0:写1读2,1:写2读1,状态转移和输出分开编码
	 reg          n_state    ;
// ------------------------------------------------------ //
    // 状态寄存器
    always @ (posedge clk or negedge rst_n)
    begin
        if(rst_n == 1'b0)
            c_state <= 'b0;
        else
            c_state <= n_state;
    end
// ------------------------------------------------------ //
    //状态转移
	always@(c_state)begin
			case(c_state)
				1'b0:n_state=1'b1;
				1'b1:n_state=1'b0;
			endcase
	end
// ------------------------------------------------------ //
    // 状态输出
    always @ (c_state)
    begin
        case(c_state)
            1'b0:
            begin
                wr_flag = 1'b0; // 写1
                rd_flag = 1'b0; // 读2
            end
            1'b1:
            begin
                wr_flag = 1'b1; // 写2
                rd_flag = 1'b1; // 读1
            end
            default:
            begin
                wr_flag = 1'b0;
                rd_flag = 1'b0;
            end
        endcase
    end
	//或者这样写
	//assign wr_flag=(c_state==1'b1)?1'b1:0;
	//assign rd_flag=(c_state==1'b1)?1'b1:0;
// ------------------------------------------------------ //
//根据wr_flag和rd_flag来进行后续操作
//1、向两个寄存器缓存数据  2、将寄存器数据输出
    // 写buffer数据
    always @ (posedge clk or negedge rst_n)
    begin
        if(rst_n == 1'b0)
        begin
            buffer1 <= 8'b0;
            buffer2 <= 8'b0;
        end
        else
        begin
            case(wr_flag)
                1'b0    : buffer1 <= data_in;  // wr_flag = 0,写buffer1
                1'b1    : buffer2 <= data_in;  // wr_flag = 1,写buffer2
                default    :
                begin
                    buffer1 <= 8'b0;
                    buffer2 <= 8'b0;
                end
            endcase
        end
    end
// ------------------------------------------------------ //
    // 读buffer数据
    always @ (posedge clk or negedge rst_n)
    begin
        if(rst_n == 1'b0)
        begin
            data_out <= 8'b0;
        end
        else
        begin
            case(rd_flag)
                1'b0    : data_out <= buffer2;   // rd_flag=0,读buffer2
                1'b1    : data_out <= buffer1;   // rd_flag=1,读buffer1
                default : data_out <= 8'b0;
            endcase
        end
    end
// ------------------------------------------------------ //
endmodule

Testbench

`timescale 1ns / 1ps


// Company: 
// Engineer:
//
// Create Date:   17:18:57 12/31/2021
// Design Name:   pingpang
// Module Name:   C:/Users/74172/Desktop/IC/FPGA/zsz_project/pingpang_buffer/eee.v
// Project Name:  pingpang_buffer
// Target Device:  
// Tool versions:  
// Description: 
//
// Verilog Test Fixture created by ISE for module: pingpang
//
// Dependencies:
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 


module eee;

	// Inputs
	reg clk;
	reg rst_n;
	reg [7:0] data_in;

	// Outputs
	wire [7:0] data_out;
	wire [7:0] buffer1;
	wire [7:0] buffer2;
	wire wr_flag;
	wire rd_flag;

	// Instantiate the Unit Under Test (UUT)
	pingpang uut (
		.clk(clk), 
		.rst_n(rst_n), 
		.data_in(data_in), 
		.data_out(data_out), 
		.buffer1(buffer1), 
		.buffer2(buffer2), 
		.wr_flag(wr_flag), 
		.rd_flag(rd_flag)
	);
	
	initial clk=0;
	always #10 clk=~clk;
	initial begin
		// Initialize Inputs
		rst_n = 0;
		// Wait 100 ns for global reset to finish
		#100;
		rst_n=1;        
		// Add stimulus here
	end
	always @(posedge clk or negedge rst_n)
    begin
        if(!rst_n)
            data_in    <= 'd0;
        else
            data_in    <= data_in + 1'b1;
    end
      
endmodule

读写标志位后,下一上升沿才能生效读写,根据仿真结果,达到了预期效果!

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值