网站高质量外链,注册公司最低多少钱,个人网页简历,变身小说 wordpress首先#xff0c;这个vivado的fifo和quartus有很大不同。
用BRAM来实现异步fifo。
vivado的fifo有复位#xff0c;在时钟信号稳定后#xff0c;复位至少三个时钟周期#xff08;读写端口的慢时钟#xff09;#xff0c;复位完成后30个时钟周期后再进行写操作#xff08…首先这个vivado的fifo和quartus有很大不同。
用BRAM来实现异步fifo。
vivado的fifo有复位在时钟信号稳定后复位至少三个时钟周期读写端口的慢时钟复位完成后30个时钟周期后再进行写操作慢时钟。
有两个模式:标准模式和预读模式。
标准模式读出的数据会比读使能延后一个时钟周期fifo的深度也会比配置的少一个。
预读模式读出的数据会与读使能同步深度会比配置的多一个。 犯下的错误顶层模块fifo的复位接到了系统复位上。
没有认真阅读正点原子开发指南忽略了深度的问题。
模块框图 时序图 代码
module fifo_wr_ctrl(input wire sys_clk , // clk_wr // 50Mhzinput wire sys_rst_n ,output wire rst_fifo ,output wire wr_clk ,output wire [7:0] wr_din ,output reg wr_en
);// parameter parameter RST_FIFO_CNT 3 ,RST_WAIT_CNT 30 ,DATA_IN_CNT 200 ; // 设置深度256但实际深度只有255.写进数据0~254// localparamlocalparam RST 4b0001 ,RST_WAIT 4b0010 ,DATA_IN_S 4b0100 ,FINISH_S 4b1000 ;// reg signal definereg [7:0] cnt_core ;reg finish ;reg [3:0] state ;// wire signal definewire rst_flag ;wire wait_flag ;wire data_over_flag ;// reg [7:0] cnt_core ;always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) cnt_core 8d0 ;else if(rst_flag || wait_flag || data_over_flag || finish)cnt_core 8d0 ;else cnt_core cnt_core 1b1 ;end// reg finish ;always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) finish 1b0 ;else if(data_over_flag)finish 1b1 ;else finish finish ;end// reg [3:0] state ;always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) state 4b0001 ;else case (state)RST : if(rst_flag)state RST_WAIT ;else state RST ;RST_WAIT : if(wait_flag)state DATA_IN_S ;else state RST_WAIT ;DATA_IN_S : if(data_over_flag)state FINISH_S ;else state DATA_IN_S ;FINISH_S : state FINISH_S ;default : state RST ;endcaseend// wire rst_flag ;assign rst_flag ((cnt_core (RST_FIFO_CNT - 1)) (state RST)) ;// wire wait_flag ;assign wait_flag ((cnt_core (RST_WAIT_CNT - 1)) (state RST_WAIT)) ;// wire data_over_flag ;assign data_over_flag ((cnt_core (DATA_IN_CNT - 1)) (state DATA_IN_S)) ;// output reg rst_fifo ,// always (posedge sys_clk or negedge sys_rst_n) begin// if(~sys_rst_n) // rst_fifo 1b1 ;// else if(state RST rst_flag)// rst_fifo 1b1 ;// else if(state RST)// rst_fifo 1b0 ;// else // rst_fifo 1b1 ; // endassign rst_fifo (state RST) ? 1b1 : 1b0 ;// output wire wr_clk ,assign wr_clk (sys_rst_n) ? sys_clk : 1b0 ;// output wire [7:0] wr_din ,assign wr_din (state DATA_IN_S) ? cnt_core : 8d0 ;// output reg wr_en ,always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) wr_en 1b0 ;else if(wait_flag || data_over_flag)wr_en ~wr_en ;else wr_en wr_en ;endendmodule
module fifo_rd_ctrl(input wire sys_clk ,// clk_rdinput wire sys_rst_n ,input wire wr_full ,input wire almost_empty,// 将要读空output reg rd_en ,output wire rd_clk
);assign rd_clk (sys_rst_n) ? sys_clk : 1b0 ;always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) rd_en 1b0 ;else if(almost_empty) // 将要读空后拉低读使能。因为是时序逻辑应该正好读空fiford_en 1b0 ;else if(wr_full) // 写满后拉高写使能rd_en 1b1 ;else rd_en rd_en ;end
endmodule
module top(input wire sys_clk ,input wire sys_rst_n ,output wire [7:0] data_out
);// 例化间连线wire clk_100Mhz ;wire clk_50Mhz ;wire locked ;wire rst_n ;wire rst_fifo ; // fifo的复位信号wire wr_clk ; // 写端口相关信号wire [7:0] wr_din ; // 写端口相关信号wire wr_en ; // 写端口相关信号wire [7:0] dout ;wire full ;wire almost_full ;wire empty ;wire almost_empty;wire [7:0] rd_data_count;wire [7:0] wr_data_count;wire wr_rst_busy ;wire rd_rst_busy ;wire rd_en ;wire rd_clk ;mmcm_100M_50M mmcm_100M_50M_inst (.resetn ( sys_rst_n ) ,.clk_in1 ( sys_clk ) ,.clk_out1 ( clk_100Mhz ) ,.clk_out2 ( clk_50Mhz ) ,.locked ( locked )
);assign rst_n sys_rst_n locked ;fifo_wr_ctrl fifo_wr_ctrl_inst(.sys_clk ( clk_50Mhz ) , // clk_wr // 50Mhz.sys_rst_n ( rst_n ) ,.rst_fifo ( rst_fifo ) ,.wr_clk ( wr_clk ) ,.wr_din ( wr_din ) ,.wr_en ( wr_en )
);fifo_rd_ctrl fifo_rd_ctrl_inst(.sys_clk ( clk_100Mhz ) ,// clk_rd.sys_rst_n ( rst_n ) ,.wr_full ( full ) ,.almost_empty ( almost_empty ) ,// 将要读空.rd_en ( rd_en ) ,.rd_clk ( rd_clk )
);fifo_256X8 fifo_256X8_inst(.rst ( rst_fifo ) , // 在fpga配置完成后fifo必须要进行复位操作?复位信号至少保?3个时钟周期以慢时钟为准?复位完成后至少经过30个时钟周期后才能进行数据写操作?.wr_clk ( wr_clk ) , // 写数据时?50Mhz // 复位高有效??.rd_clk ( rd_clk ) , // 读数据时?100Mhz.din ( wr_din ) , // 写入数据.wr_en ( wr_en ) , // 写使?.rd_en ( rd_en ) , // 读使?.dout ( data_out ) , // 输出数据.full ( full ) , // 写满.almost_full ( almost_full ) , // 将写?.empty ( empty ) , // 读空.almost_empty ( almost_empty ) , // 将读?.rd_data_count ( rd_data_count ) , // 可读数据.wr_data_count ( wr_data_count ) , // 已写数据.wr_rst_busy ( wr_rst_busy ) , // 写复位忙?.rd_rst_busy ( rd_rst_busy ) // 读复位忙?
); endmodule timescale 1ns/1ns
module test_top();reg sys_clk ;reg sys_rst_n ;wire [7:0] data_out ;top top_inst(.sys_clk ( sys_clk ) ,.sys_rst_n ( sys_rst_n ) ,.data_out ( data_out )
);parameter CYCLE 20 ;initial beginsys_clk 1b1 ;sys_rst_n 1b0 ;#( CYCLE * 5) ;sys_rst_n 1b1 ;#(3000*CYCLE) ;$stop;endalways #(CYCLE/2) sys_clk ~sys_clk ;
endmodule 仿真图