标签:解决 tput display 地址 分享图片 next reg 触发器 parameter
一、分析
2.将一个二进制的计数值从一个时钟域同步到另一个时钟域的时候很容易出现问题,因为采用二进制计数器时所有位都可能同时变化,在同一个时钟沿同步多个信号的变化会产生亚稳态问题。而使用格雷码只有一位变化,因此在两个时钟域间同步多个位不会产生问题。所以需要一个二进制到gray码的转换电路,将地址值转换为相应的gray码,然后将该gray码同步到另一个时钟域进行对比,作为空满状态的检测。
那么,多位二进制码如何转化为格雷码?
换一种描述方法:
verilog代码实现就一句:assign gray_code = (bin_code>>1) ^ bin_code;
使用gray码解决了一个问题,但同时也带来另一个问题,即在格雷码域如何判断空与满。
这里直接给出结论:
判断读空时:需要读时钟域的格雷码rgray_next和被同步到读时钟域的写指针rd2_wp每一位完全相同;
判断写满时:需要写时钟域的格雷码wgray_next和被同步到写时钟域的读指针wr2_rp高两位不相同,其余各位完全相同;
二、Verilog实现
module fifo #( parameter WSIZE = 8; parameter DSIZE = 32; ) ( input wr_clk, input rst, input wr_en, input [WSIZE-1 : 0]din, input rd_clk, input rd_en, output [WSIZE-1 : 0]dout, output reg rempty, output reg wfull ); //定义变量 reg [WSIZE-1 :0] mem [DSIZE-1 : 0]; reg [WSIZE-1 : 0] waddr,raddr; reg [WSIZE : 0] wbin,rbin,wbin_next,rbin_next; reg [WSIZE : 0] wgray_next,rgray_next; reg [WSIZE : 0] wp,rp; reg [WSIZE : 0] wr1_rp,wr2_rp,rd1_wp,rd2_wp; wire rempty_val,wfull_val; //输出数据 assign dout = mem[raddr]; //输入数据 always@(posedge wr_clk) if(wr_en && !wfull) mem[waddr] <= din; //1.产生存储实体的读地址raddr; 2.将普通二进制转化为格雷码,并赋给读指针rp always@(posedge rd_clk or negedge rst_n) if(!rst_n) {rbin,rp} <= 0; else {rbin,rp} <= {rbin_next,rgray_next}; assign raddr = rbin[WSIZE-1 : 0]; assign rbin_next = rbin + (rd_en & ~rempty); assign rgray_next = rbin_next ^ (rbin_next >> 1); //1.产生存储实体的写地址waddr; 2.将普通二进制转化为格雷码,并赋给写指针wp always@(posedge wr_clk or negedge rst_n) if(!rst_n) {wbin,wp} <= 0; else {wbin,wp} <= {wbin_next,wgray_next}; assign waddr = wbin[WSIZE-1 : 0]; assign wbin_next = wbin + (wr_en & ~wfull); assign wgray_next = wbin_next ^ (wbin_next >> 1); //将读指针rp同步到写时钟域 always@(posedge wr_clk or negedge rst_n) if(!rst_n) {wr2_rp,wr1_rp} <= 0; else {wr2_rp,wr1_rp} <= {wr1_rp,rp}; //将写指针wp同步到读时钟域 always@(posedge rd_clk or negedge rst_n) if(!rst_n) {rd2_wp,rd1_wp} <= 0; else {rd2_wp,rd1_wp} <= {rd1_wp,wp}; //产生读空信号rempty assign rempty_val = (rd2_wp == rgray_next); always@(posedge rd_clk or negedge rst_n) if(rst_n) rempty <= 1‘b1; else rempty <= rempty_val; //产生写满信号wfull assign wfull_val = ((~(wr2_rp[WSIZE : WSIZE-1]),wr2_rp[WSIZE-2 : 0]) == wgray_next); always@(posedge wr_clk or negedge rst_n) if(!rst_n) wfull <= 1‘b0; else wfull <= wfull_val; endmodule
标签:解决 tput display 地址 分享图片 next reg 触发器 parameter
原文地址:https://www.cnblogs.com/ylsm-kb/p/9068449.html