记录下数字的流程
记录数字流程
数字IC设计流程,此次举例用asyn_fifo举例,包含以下 spec->rtl mapping -> lint check->simulation -> dc ->fm - >place&rout ->RC extract ->pt ->drc/lvs/ant check
下面是asyn fifo的rtl级描述
1:top level
module asyn_fifo
#(
parameter DATA_WIDTH = 4,
parameter DATA_DEPTH = 8,
parameter PTR_WIDTH = 3
)
(
//write colck domian
wclk ,
w_rstn ,
wr_en ,
wdata ,
full ,
//read clock domain
rclk ,
r_rstn ,
rd_en ,
rdata ,
empty
);
input wclk ;
input w_rstn ;
input wr_en ;
input [DATA_WIDTH-1:0] wdata ;
output full ;
input rclk ;
input r_rstn ;
input rd_en ;
output [DATA_WIDTH-1:0] rdata ;
output empty ;
wire [PTR_WIDTH:0] w_ptr_gray;
wire [PTR_WIDTH:0] r_ptr_gray;
wire [PTR_WIDTH:0] w_ptr ;
wire [PTR_WIDTH:0] r_ptr ;
w_ctrl
#(
.PTR_WIDTH (3)
)
u_w_ctrl(
.wclk (wclk ),
.w_rstn (w_rstn ),
.wr_en (wr_en ),
.w_ptr (w_ptr ),
.w_ptr_gray (w_ptr_gray ),
.r_ptr_gray (r_ptr_gray ),
.full (full )
);
r_ctrl
#(
.PTR_WIDTH (3)
)
u_r_ctrl(
.rclk (rclk ),
.r_rstn (r_rstn ),
.rd_en (rd_en ),
.r_ptr (r_ptr ),
.w_ptr_gray (w_ptr_gray ),
.r_ptr_gray (r_ptr_gray ),
.empty (empty )
);
ram_fifo
#(
DATA_WIDTH
DATA_DEPTH
PTR_WIDTH
)
u_ram_fifo(
.wclk (wclk ),
.w_rstn (w_rstn ),
.wdata (wdata ),
.wr_en (wr_en ),
.w_ptr (w_ptr ),
.full (full ),
.rclk (rclk ),
.r_rstn (r_rstn ),
.rdata (rdata ),
.rd_en (rd_en ),
.r_ptr (r_ptr ),
.empty (empty )
);
endmodule
ram w/r crtl
module ram_fifo
#(
parameter DATA_WIDTH = 4,
parameter DATA_DEPTH = 8,
parameter PTR_WIDTH = 3
)
(
//write colck domian
wclk ,
w_rstn ,
wr_en ,
wdata ,
full ,
w_ptr ,
//read clock domain
rclk ,
r_rstn ,
rd_en ,
rdata ,
empty ,
r_ptr
);
input wclk ;
input w_rstn ;
input wr_en ;
input [DATA_WIDTH-1:0] wdata ;
output full ;
input w_ptr ;
input rclk ;
input r_rstn ;
input rd_en ;
output [DATA_WIDTH-1:0] rdata ;
output [PTR_WIDTH:0] empty ;
input [PTR_WIDTH:0] r_ptr ;
reg [DATA_WIDTH-1:0] mem_array [0:DATA_DEPTH-1];
integer i;
always @(posedge mclk or negedge r_rstn)
begin
if(!w_rstn)
begin
for(i=0;i<DATA_DEPTH;i=i+1)
begin
men_array[i] <= 4'b0000;
end
end
else if(wr_en && !full)
mem_array[w_ptr[PTR_WIDTH-1:0]] <= wdata;
end
always @(posedge rclk or negedge r_rstn)
begin
if(!r_rstn)
rdata <= 4'd0;
else if(rd_en && !empty)
rdata <= men_array[r_ptr[PTR_WIDTH-1:0]];
end
endmodule
read ctrl
module r_ctrl
#(
parameter PTR_WIDTH = 3
)
(
rclk ,
r_rstn ,
rd_en ,
empty ,
w_ptr_gray ,
r_ptr_gray ,
r_ptr
);
input rclk ;
input r_rstn ;
input rd_en ;
input [PTR_WIDTH:0] w_ptr_gray;
output reg [PTR_WIDTH:0] r_ptr_gray;
output reg [PTR_WIDTH:0] r_ptr ;
output reg empty ;
reg [PTR_WIDTH:0] w_ptr_gray_d2,w_ptr_gray_d1;
reg [PTR_WIDTH:0] r_ptr_gray_w ;
always @(posedge rclk or negedge r_rstn)
begin
if(!r_rstn)
r_ptr <= 'd0;
else if(rd_en && !empty)
r_ptr <= r_ptr + 1'b1;
end
always @(posedge rclk or negedge r_rstn)
begin
if(!r_rstn)
begin
w_ptr_gray_d1 <= 'd0;
w_ptr_gray_d2 <= 'd0;
end
else
begin
w_ptr_gray_d1 <= w_ptr_gray ;
w_ptr_gray_d2 <= w_ptr_gray_d1;
end
end
always @(*)
begin
if(!r_rstn)
empty = 1'b0;
else if(r_ptr_gray == w_ptr_gray_d2)
empty = 1'b1;
else
empty = 1'b0;
end
//read bin2gray
assign r_ptr_gray_w = r_ptr ^ (r_ptr >> 1'b1)
always @(posedge rclk or negedge r_rstn)
if(!r_rstn)
r_ptr_gray <= 'd0;
else
r_ptr_gray <= r_ptr_gray_w;
endmodule
write ctrl
module w_ctrl
#(
parameter PTR_WIDTH = 3
)
(
//write colck domian
wclk ,
w_rstn ,
wr_en ,
r_ptr_gary ,
w_ptr_gray ,
w_ptr ,
full
);
input wclk ;
input w_rstn ;
input wr_en ;
input [PTR_WIDTH:0] r_ptr_gray;
output reg [PTR_WIDTH:0] w_ptr_gray;
output reg [PTR_WIDTH:0] w_ptr ;
output full ;
reg [PTR_WIDTH:0] r_ptr_gray_d2,r_ptr_gray_d1;
wire [PTR_WIDTH:0] w_ptr_gray_w ;
//wclk ptr write addr
always @(posedge wclk or negedge w_rstn)
begin
if(!w_rstn)
w_ptr <= 'd0;
else if(wr_en && !full)
w_ptr <= w_ptr + 1'b1;
end
always @(posedge wclk or negedge w_rstn)
begin
if(!w_rstn)
begin
r_ptr_gray_d2 <= 'd0;
r_ptr_gray_d1 <= 'd0;
end
else
begin
r_ptr_gray_d2 <= r_ptr_gray_d1;
r_ptr_gray_d1 <= r_ptr_gray ;
end
always @(*)
begin
if(!w_rstn)
full = 1'b0;
else if(w_ptr_gray =={~r_ptr_gray_d2[PTR_WIDTH:PTR_WIDTH-1],r_ptr_gray_d2[PTR_WIDTH-2:0]})
full = 1'b1;
else
full = 1'b0;
//wclk domian bin2gray
assign w_ptr_gray_w = w_ptr ^ (w_ptr >> 1);
always @(posedge wclk or negedge w_rstn)
if(!w_rstn)
w_ptr_gray <= 'd0;
else
w_ptr_gray <= w_ptr_gray_w;
endmodule
关于fifo的文章资源很多。其中原理就不介绍。下一篇是代码的lint check