为了准备笔试及面试可能遇到的常见题型,特地来记录一下。
1. 跨时钟域处理
单bit跨时钟域
快到慢
脉冲检测:
- PS:需要进行脉冲展宽,要求快时钟域两个脉冲间有一定的时间间隔.
module f2s_1bit(
input rstn,
input clk_fast,
input vld_i,
input clk_slow,
output vld_o
);
reg fast_flag;
reg dly1,dly2,dly3;
wire edge_flag;
always@(posedge clk_fast or negedge rstn)begin
if(!rstn)
fast_flag <= 1'b0;
else if(vld_i)
fast_flag <= ~fast_flag;
end
always@(posedge clk_slow or negedge rstn)begin
if(!rstn)begin
dly1 <= 1'b0;
dly2 <= 1'b0;
dly3 <= 1'b0;
end
else begin
dly1 <= fast_flag;
dly2 <= dly1;
dly3 <= dly2;
end
end
assign edge_flag = dly2^dly3;
assign vld_o = edge_flag;
endmodule
- 电平同步:
慢到快
直接打两拍进行。
多bit跨时钟
- 采用DMUX技术进行多bit化为单bit,进行跨时钟域处理。
- 采用异步FIFO方式进行同步。
- 握手信号进行同步。
同步FIFO
- 结构:读写地址指针,mem,空满信号判断
module sfifo#(
parameter DATA_WIDTH = 8,
parameter DEPTH = 8
)(
input rstn,
input clk,
input wr_en,
input [DATA_WIDTH-1:0] din,
input rd_en,
output [DATA_WIDTH-1:0] dout,
output reg full,
output reg empty
);
localparam ADDR_WIDTH = log2(DEPTH);
wire wr_vld,rd_vld;
reg [ADDR_WIDTH-1:0] wr_ptr_next,wr_ptr,rd_ptr_next,rd_ptr;
reg [ADDR_WIDTH-1:0] cnt;//计数器模式
//读写使能
assign wr_vld = wr_en & (~full);
assign rd_vld = rd_en & (~empty);
//写指针
always@* begin
if(wr_vld)
wr_ptr_next = wr_ptr + 1'b1;
else
wr_ptr_next = wr_ptr;
end
always @(posedge clk or negedge rstn) begin
if (rstn == 1'b0)
wr_ptr <= {ADDR_WIDTH{1'b0}};
else
wr_ptr <= wr_ptr_next;
end
//读指针
always@* begin
if(rd_vld)
rd_ptr_next = rd_ptr + 1'b1;
else
rd_ptr_next = rd_ptr;
end
always @(posedge clk or negedge rstn) begin
if (rstn == 1'b0)
rd_ptr <= {ADDR_WIDTH{1'b0}};
else
rd_ptr <= rd_ptr_next;
end
//空满判断方式1:空满判断计数器//该种方式随着后续深度的增加,比较器的效率降低,会导致频率降低
always@(posedge clk or negedge rstn)begin
if(!rstn)
cnt <= {DEPTH{1'b0}};
else
case ({wr_vld,rd_vld})
2'b10:
cnt <= cnt + 1'b1;
2'b01:
cnt <= cnt - 1'b1;
default:;
endcase
end
//空判断
assign empty = cnt=={DEPTH{1'b0}};
//满判断
assign full = cnt==DEPTH;
//ram例化即mem
ram #(
.DATA_WIDTH(DATA_WIDTH),
.ADDR_WIDTH(ADDR_WIDTH)
) inst_ram (
.rstn (rstn),
.clk (clk),
.wr_vld (wr_vld),
.wr_addr (wr_ptr[ADDR_WIDTH-1:0]),
.din (din),
.rd_vld (rd_vld),
.rd_addr (rd_ptr[ADDR_WIDTH-1:0]),
.dout (dout)
);
function integer log2; //实现log2计算,用以计算深度对应的位宽
input integer din;
begin
din = din-1;
for(log2=0;din>0;log2=log2+1)
din = din >> 1;
end
endfunction
endmodule
- 空满判断方式二rtl
//空满判断方式2
always@(posedge clk or negedge rstn)begin
if(!rstn)
wr_ptr <= {ADDR_WIDTH{1'b0}};
else if(wr_vld)
wr_ptr <= wr_ptr + 1'b1;
end
always@(posedge clk or negedge rstn)begin
if(!rstn)
rd_ptr <= {ADDR_WIDTH{1'b0}};
else if(rd_vld)
rd_ptr <= wr_ptr + 1'b1;
end
assign empty = rd_ptr == wr_ptr;
assign full = {~rd_ptr[ADDR_WIDTH],rd_ptr[ADDR_WIDTH-1:0]} == wr_ptr;
异步FIFO
- 结构:读写地址指针,mem,格雷码跨时钟域处理,空满信号判断
5 条评论
《赫尔克里士国语》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/152929.html
不错不错,我喜欢看 https://www.ea55.com/
怎么收藏这篇文章?
看的我热血沸腾啊
不错不错,我喜欢看 https://www.jiwenlaw.com/