add sync_1bit and modify sync_fifo.v

This commit is contained in:
yunlongLi 2024-10-31 17:17:12 +08:00
parent 2720a9648f
commit 8ba3eab367
2 changed files with 314 additions and 8 deletions

177
common/sync_1bit.v Normal file
View File

@ -0,0 +1,177 @@
//==========================================================
//--Author : colonel
//--Date : 10-31
//--Module : sync_1bit_from_slow_2_fast
//--Function: sync 1bit from slow clk to fast clk
//==========================================================
module sync_1bit_from_slow_2_fast(
//==========================< 端口 >=========================
input wire slow_clk,
input wire rst_n,
input wire din,
input wire fast_clk,
output wire sync_dout
);
//==========================< 信号 >=========================
reg din_ff0,din_ff1,din_ff2;
//=========================================================
//-- din_ff0 : sync from slow_clk
//=========================================================
always @(posedge slow_clk or negedge rst_n) begin
if (!rst_n) begin
din_ff0 <= 1'b0;
end else begin
din_ff0 <= din;
end
end
//=========================================================
//-- din_ff1 : sync from fast_clk
//=========================================================
always @(posedge fast_clk or negedge rst_n) begin
if (!rst_n) begin
din_ff1 <= 0;
din_ff2 <= 0;
end else begin
din_ff1 <= din_ff0;
din_ff2 <= din_ff1;
end
end
assign sync_dout = din_ff2;
endmodule
//==========================================================
//--Author : colonel
//--Date : 10-31
//--Module : sync_1bit_from_fast_2_slow_pulse_widen
//--Function: sync 1bit from fast clk to slow clk
//==========================================================
module sync_1bit_from_fast_2_slow_pulse_widen(
//==========================< 端口 >=========================
input wire fast_clk,
input wire rst_n,
input wire din,
input wire slow_clk,
output wire dout
);
//==========================< 信号 >=========================
reg din_fast_r;
//=========================================================
//-- din_fast_r: 将脉冲信号在快时钟域展平为电平信号即展宽脉冲信号在两次脉冲信号之间为电平信号
//=========================================================
always @(posedge fast_clk or negedge rst_n) begin
if (!rst_n) begin
din_fast_r <= 'b0;
end else begin
din_fast_r <= din ? (~din_fast_r) : din_fast_r;
end
end
//==========================< 信号 >=========================
reg data_slow_ff1;
reg data_slow_ff2;
reg data_slow_ff3;
//=========================================================
//-- data_slow_ff1/2/3: 将展宽的脉冲信号在慢时钟域打三拍并检测边沿
//=========================================================
always @(posedge slow_clk or negedge rst_n) begin
if (!rst_n) begin
data_slow_ff1 <= 'b0;
data_slow_ff2 <= 'b0;
data_slow_ff3 <= 'b0;
end else begin
data_slow_ff1 <= din_fast_r;
data_slow_ff2 <= data_slow_ff1;
data_slow_ff3 <= data_slow_ff2;
end
end
assign dout = data_slow_ff3 ^ data_slow_ff2;
endmodule
//==========================================================
//--Author : colonel
//--Date : 10-31
//--Module : sync_1bit_from_fast_2_slow_handshake
//--Function: sync 1bit from fast clk to slow clk
//==========================================================
module sync_1bit_from_fast_2_slow_handshake(
//==========================< 端口 >=========================
input wire fast_clk,
input wire rst_n,
input wire din_pulse,
input wire slow_clk,
output wire dst_pulse
);
//==========================< 信号 >=========================
reg src_sync_req;
reg src_sync_ack;
reg src_req_ff1,src_req_ff2,src_req_ff3;
//=========================================================
//-- src_sync_req:
//=========================================================
always @(posedge fast_clk or negedge rst_n) begin
if (!rst_n) begin
src_sync_req <= 1'b0;
end else begin
if (din_pulse) begin
src_sync_req <= 1'b1;
end else if(src_sync_ack) begin
src_sync_req <= 1'b0;
end else begin
src_sync_req <= src_sync_req;
end
end
end
//=========================================================
//-- src_req_ff1/2
//=========================================================
always @(posedge slow_clk or negedge rst_n) begin
if (!rst_n) begin
src_req_ff1 <= 'b0;
src_req_ff2 <= 'b0;
src_req_ff3 <= 'b0;
end else begin
src_req_ff1 <= src_sync_req;
src_req_ff2 <= src_req_ff1;
src_req_ff3 <= src_req_ff2;
end
end
wire dst_sync_ack = src_req_ff2;
//=========================================================
//-- src_sync_ack
//=========================================================
reg dst_sync_ack_ff1;
reg dst_sync_ack_ff2;
always @(posedge fast_clk or negedge rst_n) begin
if (!rst_n) begin
dst_sync_ack_ff1 <= 'b0;
dst_sync_ack_ff2 <= 'b0;
end else begin
dst_sync_ack_ff1 <= dst_sync_ack;
dst_sync_ack_ff2 <= dst_sync_ack_ff1;
end
end
assign src_sync_ack = dst_sync_ack_ff2;
//=========================================================
//-- dst_pulse
//=========================================================
assign dst_pulse = src_req_ff3 & ! src_req_ff2;
endmodule

View File

@ -1,11 +1,11 @@
//====================================
//==========================================================
//--Author : colonel
//--Date : 10-30
//--Module : sync_fifo
//--Function: the sync clk fifo logic
//====================================
//--Module : sync_fifo_cnt
//--Function: the sync_fifo logic using cnt way
//==========================================================
module sync_fifo #(
module sync_fifo_cnt_way #(
//==========================< 参数 >=========================
parameter DATA_WIDTH = 8,
parameter FIFO_DEPTH = 16
@ -24,12 +24,13 @@ module sync_fifo #(
);
//==========================< 参数 >=========================
localparam DATA_DEPTH = $clog2(DATA_WIDTH);
localparam FIFO_DEPTH_WIDTH = $clog2(FIFO_DEPTH);
//==========================< 信号 >=========================
reg [DATA_WIDTH -1:0] fifo_mem[FIFO_DEPTH];
reg [DATA_DEPTH -1:0] fifo_cnt;
reg [DATA_DEPTH -1:0] wr_ptr;
reg [DATA_DEPTH -1:0] rd_ptr;
reg [FIFO_DEPTH_WIDTH -1:0] fifo_cnt;
reg [FIFO_DEPTH_WIDTH -1:0] wr_ptr;
reg [FIFO_DEPTH_WIDTH -1:0] rd_ptr;
//=========================================================
@ -131,7 +132,135 @@ always @(posedge clk or negedge rst_n) begin
end
end
//=========================================================
//-- wr_full,rd_empty
//=========================================================
assign wr_full = fifo_cnt == FIFO_DEPTH;
assign rd_empty= fifo_cnt == 0;
endmodule
//==========================================================
//--Author : colonel
//--Date : 10-31
//--Module : sync_fifo_addy_way
//--Function: the sync_fifo logic using addr way
//==========================================================
module sync_fifo_addr_way #(
//==========================< 参数 >=========================
parameter DATA_WIDTH = 8,
parameter FIFO_DEPTH = 16
) (
//==========================< 端口 >=========================
input wire clk,
input wire rst_n,
input wire wr_en,
input wire [DATA_WIDTH -1:0] write_data,
output wire wr_full,
input wire rd_en,
input wire [DATA_WIDTH -1:0] read_data,
output wire rd_empty
);
//==========================< 参数 >=========================
localparam DATA_DEPTH = $clog2(DATA_WIDTH);
localparam FIFO_DEPTH_WIDTH = $clog2(FIFO_DEPTH);
//==========================< 信号 >=========================
reg [DATA_WIDTH -1:0] fifo_mem[FIFO_DEPTH -1:0];
reg [FIFO_DEPTH_WIDTH :0] wr_ptr;
reg [FIFO_DEPTH_WIDTH :0] rd_ptr;
//=========================================================
//-- write_data
//=========================================================
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
fifo_mem[wr_ptr] <= 0;
end else begin
if (wr_en && !wr_full) begin
fifo_mem[wr_ptr] <= write_data;
end else begin
fifo_mem[wr_ptr] <= fifo_mem[wr_ptr] ;
end
end
end
//=========================================================
//-- wr_ptr
//=========================================================
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
wr_ptr <= 0;
end else begin
if(!wr_full && wr_en && (wr_ptr[FIFO_DEPTH_WIDTH -1:0] < (FIFO_DEPTH -1))) begin
wr_ptr <= wr_ptr + 1'b1;
end else if(!wr_full && wr_en && (wr_ptr[FIFO_DEPTH_WIDTH -1:0] == (FIFO_DEPTH -1))) begin
wr_ptr[FIFO_DEPTH_WIDTH] <= ~wr_ptr[FIFO_DEPTH_WIDTH];
wr_ptr[FIFO_DEPTH_WIDTH -1:0] <= 0;
end else begin
wr_ptr <= wr_ptr;
end
end
end
//=========================================================
//-- write_data
//=========================================================
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
fifo_mem[wr_ptr] <= 'b0;
end else begin
if(!wr_full && wr_en) begin
fifo_mem[wr_ptr] <= write_data;
end else begin
fifo_mem[wr_ptr] <= fifo_mem[wr_ptr];
end
end
end
//=========================================================
//-- rd_ptr
//=========================================================
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
rd_ptr <= 'b0;
end else begin
if (!rd_empty && rd_en && (rd_ptr[FIFO_DEPTH_WIDTH -1:0] < (FIFO_DEPTH-1))) begin
rd_ptr <= rd_ptr + 1'b1;
end else if (!rd_empty && rd_en && (rd_ptr[FIFO_DEPTH_WIDTH -1:0] == (FIFO_DEPTH-1))) begin
rd_ptr[FIFO_DEPTH_WIDTH] <= ~rd_ptr[FIFO_DEPTH_WIDTH];
rd_ptr[FIFO_DEPTH_WIDTH -1:0] <= 'b0;
end else begin
rd_ptr <= rd_ptr;
end
end
end
//=========================================================
//-- read_data
//=========================================================
reg [DATA_WIDTH -1:0] read_data_tmp;
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
read_data_tmp <= 'b0;
end else begin
if (!rd_empty && rd_en) begin
read_data_tmp <= fifo_mem[rd_ptr];
end else begin
read_data_tmp <= read_data_tmp;
end
end
end
assign read_data = read_data_tmp;
//=========================================================
//-- wr_full,rd_empty
//=========================================================
assign wr_full = (wr_ptr[FIFO_DEPTH_WIDTH] != rd_ptr[FIFO_DEPTH_WIDTH]) && (wr_ptr[FIFO_DEPTH_WIDTH -1:0] == rd_ptr[FIFO_DEPTH_WIDTH -1:0]);
assign rd_empty= (wr_ptr[FIFO_DEPTH_WIDTH] == rd_ptr[FIFO_DEPTH_WIDTH]) && (wr_ptr[FIFO_DEPTH_WIDTH -1:0] == rd_ptr[FIFO_DEPTH_WIDTH -1:0]);
endmodule