异步FIFO的实现

写进FIFO数据时钟为clk.assp(5MHz),读入FIFO数据时钟为clk.sys(50MHz);写入的数据为rom中depth=32,wedth=16的数据;rom中原数据为8bits,需将气如fifo_input同步,将rom数据其改为16bits

`timescale 1ns / 1ps
//
module fifo_test(
			input clk,		          //50MHz时钟
			input rst_n	             //复位信号,低电平有效	
		);

//-----------------------------------------------------------
localparam      W_IDLE      = 1;
localparam      W_FIFO     = 2; 
localparam      R_IDLE      = 1;
localparam      R_FIFO     = 2; 

reg[2:0]  write_state;
reg[2:0]  next_write_state;
reg[2:0]  read_state;
reg[2:0]  next_read_state;
reg [4:0]rom_addra;

//reg[15:0] w_data;	   //FIFO写数据
wire[15:0] w_data;
wire      wr_en;	   //FIFO写使能
wire      rd_en;	   //FIFO读使能
wire[15:0] r_data;	//FIFO读数据
wire       full;  	//FIFO满信号 
wire       empty;  	//FIFO空信号 
wire[8:0]  rd_data_count;  	
wire[8:0]  wr_data_count;  
wire clk_sys;
wire clk_assp;
clock clock_div
(// Clock in ports
 .CLK_IN1(clk),      // IN
 // Clock out ports
 .clk_sys(clk_sys),     // OUT
 .clk_assp(clk_assp)); 

///产生FIFO写入的数据
always@(posedge clk_sys or negedge rst_n)
begin
	if(rst_n == 1'b0)
		write_state <= W_IDLE;
	else
		write_state <= next_write_state;
end

always@(*)
begin
	case(write_state)
		W_IDLE:
//			if(empty == 1'b1)               //FIFO空, 开始写FIFO
			if(full!=1)							 //FIFO非满, 开始写FIFO
				next_write_state <= W_FIFO;
			else
				next_write_state <= W_IDLE;
		W_FIFO:
			if(full == 1'b1)                //FIFO满
				next_write_state <= W_IDLE;
			else
				next_write_state <= W_FIFO;
		default:
			next_write_state <= W_IDLE;
	endcase
end

assign wr_en = (next_write_state == W_FIFO) ? 1'b1 : 1'b0; 

//
//always@(posedge clk_sys or negedge rst_n)
//begin
//	if(rst_n == 1'b0)
//		w_data <= 16'd0;
//	else
//	   if (wr_en == 1'b1)
//		    w_data <= w_data + 1'b1;
//		else
//          w_data <= 16'd0;		
//end

always@(posedge clk_assp or negedge rst_n)
if(!rst_n)
rom_addra<=0;
else if(rom_addra==5'd31)
rom_addra<=0;
else 
rom_addra<=rom_addra+1;
//从rom中读入数据

rom_output_fifo rom_data (
  .clka(clk_sys), // input clka
  .addra(rom_addra), // input [4 : 0] addra
  .douta(w_data) // output [15 : 0] douta
);

///产生FIFO读的数据
always@(posedge clk_sys or negedge rst_n)
begin
	if(rst_n == 1'b0)
		read_state <= R_IDLE;
	else
		read_state <= next_read_state;
end

always@(*)
begin
	case(read_state)
		R_IDLE:
//			if(full == 1'b1)               //FIFO满, 开始读FIFO
			if(empty!=1) 				 //FIFO非空, 开始读FIFO
				next_read_state <= R_FIFO;
			else
				next_read_state <= R_IDLE;
		R_FIFO:
			if(empty == 1'b1)              //FIFO满
				next_read_state <= R_IDLE;
			else
				next_read_state <= R_FIFO;
		default:
			next_read_state <= R_IDLE;
	endcase
end

assign rd_en = (next_read_state == R_FIFO) ? 1'b1 : 1'b0; 

//-----------------------------------------------------------
//实例化FIFO
fifo_ip fifo_ip_inst (
  .rst            (~rst_n       ),   // input rst
  .wr_clk         (clk_assp          ),   // input wr_clk
  .rd_clk         (clk_sys          ),   // input rd_clk
  .din            (w_data       ),   // input [15 : 0] din
  .wr_en          (wr_en        ),   // input wr_en
  .rd_en          (rd_en        ),   // input rd_en
  .dout           (r_data       ),   // output [15 : 0] dout
  .full           (full         ),   // output full
  .empty          (empty        ),   // output empty
  .rd_data_count  (rd_data_count),   // output [8 : 0] rd_data_count
  .wr_data_count  (wr_data_count)    // output [8 : 0] wr_data_count
);


wire [35:0]   CONTROL0;
wire [255:0]  TRIG0;
chipscope_icon icon_debug (
    .CONTROL0(CONTROL0) // INOUT BUS [35:0]
);

chipscope_ila ila_filter_debug (
    .CONTROL(CONTROL0), // INOUT BUS [35:0]
    .CLK(clk_sys),          // IN
    .TRIG0(TRIG0)      // IN BUS [255:0]
);                                                     

assign  TRIG0[15:0]=w_data;  
assign  TRIG0[16]=wr_en;  	
assign  TRIG0[32:17]=r_data;  
assign  TRIG0[33]=rd_en; 
assign  TRIG0[34]=full;
assign  TRIG0[35]=empty;
assign  TRIG0[44:36]=rd_data_count;  	
assign  TRIG0[53:45]=wr_data_count; 

endmodule


chipscope信号查看结果如下
在这里插入图片描述
从图看出fifo full一直为0,这是因为读时钟为50MHz,而写时钟为5MHz,读的速度远高于写的速度,同时写使能一直为高,读使能偶尔为高,empty偶尔才能为低,说明读的速度远高于写的速度;
可用于一般的外设写入FPGA,外设写入速度远低于FPGA读取寄存器速度的时候,运用FIFO作为数据传输;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值