原创 乒乓操作1(用寄存器做缓存)

2010-1-22 00:11 6212 12 14 分类: FPGA/CPLD

这几天在研究FPGA的乒乓操作,乒乓操作的理论很多参考书、网上的资料都有讲解,这里我就不啰嗦了,我想分四个部分来研究乒乓操作:


一、用寄存器做缓存,一次可以缓存N bit的数据


二、用FPGA内部RAM做缓存,要用到两块RAM


三、用FPGA内部的真正的双口RAM做缓存,用一块双口RAM即可


四、用外部的两块SRAM做缓存


 


先给出第一部分的设计内容,其余的将在后面给出,欢迎大家指教,谢谢


设计源码:


module pingpang( clk        ,
                             rst_n    ,
                            data_in  ,   //输入数据
                            data_out    //输出数据
                             );


   input               clk       ;
   input              rst_n     ;
   input     [7:0] data_in  ;
   output   [7:0] data_out;
  
   reg     [7:0] data_out;
   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,wr_flag = 1,读buffer1
   reg             state      ;    //状态机, 0:写1读2, 1:写2读1 ,状态转移和输出分开编码
   
   always @ (posedge clk or negedge rst_n)   //状态转移
     begin
        if(rst_n == 1'b0) state   <= 1'b0;
        else
          begin
             case(state)
                1'b0     : state   <= 1'b1;
                1'b1     : state   <= 1'b0;
                default  : state   <= 1'b0;
             endcase
          end
     end
    
   always @ (state )     //状态输出
     begin
      case(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
  
     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
                  2'b1     : buffer2 <= data_in;   //wr_flag = 1 ,写buffer2
                  default : begin
                               buffer1 <= 8'b0;
                               buffer2 <= 8'b0;
                            end
                endcase
            end 
       end
      
       always @ (posedge clk or negedge rst_n)
         begin
            if(rst_n == 1'b0) data_out <= 8'b0;
            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
  


test bench:


module pingpang_tb_v;


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


 // Outputs
 wire [7:0] data_out;
 


 // Instantiate the Unit Under Test (UUT)
 pingpang uut (
  .clk         (clk       ),
  .rst_n      (rst_n     ),
  .data_in  (data_in  ),
  .data_out(data_out)
 );


 initial
   begin
  // Initialize Inputs
     clk     = 0;
     rst_n   = 0;
     data_in = 0;  
     #100;
       rst_n = 1;
     end
     
   always #10 clk = ~clk;
  
   always @ (posedge clk or negedge rst_n)
     begin
      if(rst_n == 1'b0) data_in <= 8'b0;
     else                     data_in <= data_in + 1'b1;
   end  
  
endmodule


RTL试图:


点击看大图


仿真图:


 


点击看大图


从仿真波形图可以看出,乒乓操作实现了数据的无缝连接。我的程序首先执行的是写1读2,怎么验证第一个数据是从2出来的啊,大家可以想一想,其实比较简单:


  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
                  2'b1     : buffer2 <= data_in;   //wr_flag = 1 ,写buffer2
                  default : begin
                               buffer1 <= 8'b0;
                               buffer2 <= 8'b0;
                            end
                endcase
            end 
       end

将上面程序中复位时buffer2的值,变成其他的值就可以了,然后在仿真就可以看到第一个数是从buffer2中读出,大家可以去试试,我已经试过了


 

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

用户218240 2011-1-6 15:14

博主,请问撒时把2,3,4部分补上啊,十分关注

用户1626244 2010-3-22 11:22

请问下博主,如何在modelsim中显示中间变量的波形?
相关推荐阅读
用户244280 2011-04-09 02:19
有源晶振的EMC设计
    有源晶振的电路设计常见有两种:(1)、 (2)、原理图设计要点:(1)、晶振电源去耦非常重要,建议加磁珠,去耦电容选三个,容值递减。(2)、时钟输出管脚加匹配,具体匹配阻值,可根据测试结果而定...
用户244280 2011-04-05 12:46
三极管开关电路之一(基本电路)
       在板卡设计中,三极管开关电路用得非常多,然而却经常被人忽视。一位同事曾经对我说,都什么时代了,还用三极管。但是用得好的话,绝对事半功倍。        在最近的一次板卡上机调试中,由于板...
用户244280 2010-07-17 00:12
远征军魂
              今天重温了一下那段历史,一段被经历过的老年人时刻萦绕在脑海无法忘却,被浮躁的中年人忘却,被无知的青年一无所知的历史-----中国远征军。        看完凤凰大视野的那段...
用户244280 2010-06-22 22:13
毛主席词一首
     我很喜欢毛主席的一些诗词,经常去诵读,下面是毛主席的一首词,是红军长征过程中,攻占了娄山关后毛主席写的,词如下:  忆秦娥-娄山关    西风烈   长空雁叫霜晨月   霜晨月   马蹄声碎...
用户244280 2010-06-22 22:04
与君分享---我的一首词
南国冬暖阳花红枝未枯枝未枯好景处处无心留顾 十年漫漫寒窗苦满心抱负却无路却无路愁绪千千泪如雨注...
用户244280 2010-06-22 22:03
我的诗两首
     其一 孤坐仰苍穹星辰月当空又是中秋夜愁绪谁能懂          其二荔园初夏杨柳垂,晓风拂来破静水,怎奈此景无限悲,前途何方愁相随!...
EE直播间
更多
我要评论
2
12
关闭 站长推荐上一条 /3 下一条