mirror of
https://github.com/alexforencich/verilog-ethernet.git
synced 2025-01-28 07:03:08 +08:00
merged changes in axis
This commit is contained in:
commit
b765c78f56
@ -484,8 +484,8 @@ assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}};
|
||||
assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}};
|
||||
assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}};
|
||||
|
||||
// enable ready input next cycle if output is ready or if both output registers are empty
|
||||
assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && !m_axis_tvalid_reg);
|
||||
// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input)
|
||||
assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int));
|
||||
|
||||
always @* begin
|
||||
// transfer sink ready state to source
|
||||
|
@ -236,8 +236,8 @@ assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {M_ID_WIDTH{1'b0}};
|
||||
assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}};
|
||||
assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}};
|
||||
|
||||
// enable ready input next cycle if output is ready or if both output registers are empty
|
||||
assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && !m_axis_tvalid_reg);
|
||||
// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input)
|
||||
assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int));
|
||||
|
||||
always @* begin
|
||||
// transfer sink ready state to source
|
||||
|
@ -58,8 +58,11 @@ module axis_async_fifo #
|
||||
parameter USER_ENABLE = 1,
|
||||
// tuser signal width
|
||||
parameter USER_WIDTH = 1,
|
||||
// number of output pipeline registers
|
||||
parameter PIPELINE_OUTPUT = 2,
|
||||
// number of RAM pipeline registers
|
||||
parameter RAM_PIPELINE = 1,
|
||||
// use output FIFO
|
||||
// When set, the RAM read enable and pipeline clock enables are removed
|
||||
parameter OUTPUT_FIFO_ENABLE = 0,
|
||||
// Frame FIFO mode - operate on frames instead of cycles
|
||||
// When set, m_axis_tvalid will not be deasserted within a frame
|
||||
// Requires LAST_ENABLE set
|
||||
@ -121,13 +124,10 @@ module axis_async_fifo #
|
||||
|
||||
parameter ADDR_WIDTH = (KEEP_ENABLE && KEEP_WIDTH > 1) ? $clog2(DEPTH/KEEP_WIDTH) : $clog2(DEPTH);
|
||||
|
||||
parameter OUTPUT_FIFO_ADDR_WIDTH = RAM_PIPELINE < 2 ? 3 : $clog2(RAM_PIPELINE*2+7);
|
||||
|
||||
// check configuration
|
||||
initial begin
|
||||
if (PIPELINE_OUTPUT < 1) begin
|
||||
$error("Error: PIPELINE_OUTPUT must be at least 1 (instance %m)");
|
||||
$finish;
|
||||
end
|
||||
|
||||
if (FRAME_FIFO && !LAST_ENABLE) begin
|
||||
$error("Error: FRAME_FIFO set requires LAST_ENABLE set (instance %m)");
|
||||
$finish;
|
||||
@ -212,10 +212,9 @@ reg [WIDTH-1:0] mem[(2**ADDR_WIDTH)-1:0];
|
||||
reg [WIDTH-1:0] mem_read_data_reg;
|
||||
reg mem_read_data_valid_reg = 1'b0;
|
||||
|
||||
wire [WIDTH-1:0] s_axis;
|
||||
|
||||
reg [WIDTH-1:0] m_axis_pipe_reg[PIPELINE_OUTPUT-1:0];
|
||||
reg [PIPELINE_OUTPUT-1:0] m_axis_tvalid_pipe_reg = 1'b0;
|
||||
(* shreg_extract = "no" *)
|
||||
reg [WIDTH-1:0] m_axis_pipe_reg[RAM_PIPELINE+1-1:0];
|
||||
reg [RAM_PIPELINE+1-1:0] m_axis_tvalid_pipe_reg = 0;
|
||||
|
||||
// full when first TWO MSBs do NOT match, but rest matches
|
||||
// (gray code equivalent of first MSB different but rest same)
|
||||
@ -258,6 +257,8 @@ reg good_frame_sync4_reg = 1'b0;
|
||||
|
||||
assign s_axis_tready = (FRAME_FIFO ? (!full_cur || (full_wr && DROP_OVERSIZE_FRAME) || DROP_WHEN_FULL) : !full) && !s_rst_sync3_reg;
|
||||
|
||||
wire [WIDTH-1:0] s_axis;
|
||||
|
||||
generate
|
||||
assign s_axis[DATA_WIDTH-1:0] = s_axis_tdata;
|
||||
if (KEEP_ENABLE) assign s_axis[KEEP_OFFSET +: KEEP_WIDTH] = s_axis_tkeep;
|
||||
@ -267,23 +268,18 @@ generate
|
||||
if (USER_ENABLE) assign s_axis[USER_OFFSET +: USER_WIDTH] = s_axis_tuser;
|
||||
endgenerate
|
||||
|
||||
wire m_axis_tvalid_pipe = m_axis_tvalid_pipe_reg[PIPELINE_OUTPUT-1];
|
||||
wire [WIDTH-1:0] m_axis = RAM_PIPELINE ? m_axis_pipe_reg[RAM_PIPELINE+1-1] : mem_read_data_reg;
|
||||
|
||||
wire [DATA_WIDTH-1:0] m_axis_tdata_pipe = m_axis_pipe_reg[PIPELINE_OUTPUT-1][DATA_WIDTH-1:0];
|
||||
wire [KEEP_WIDTH-1:0] m_axis_tkeep_pipe = KEEP_ENABLE ? m_axis_pipe_reg[PIPELINE_OUTPUT-1][KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}};
|
||||
wire m_axis_tlast_pipe = LAST_ENABLE ? m_axis_pipe_reg[PIPELINE_OUTPUT-1][LAST_OFFSET] : 1'b1;
|
||||
wire [ID_WIDTH-1:0] m_axis_tid_pipe = ID_ENABLE ? m_axis_pipe_reg[PIPELINE_OUTPUT-1][ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}};
|
||||
wire [DEST_WIDTH-1:0] m_axis_tdest_pipe = DEST_ENABLE ? m_axis_pipe_reg[PIPELINE_OUTPUT-1][DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}};
|
||||
wire [USER_WIDTH-1:0] m_axis_tuser_pipe = USER_ENABLE ? m_axis_pipe_reg[PIPELINE_OUTPUT-1][USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}};
|
||||
wire m_axis_tvalid_pipe = m_axis_tvalid_pipe_reg[RAM_PIPELINE+1-1];
|
||||
|
||||
assign m_axis_tvalid = m_axis_tvalid_pipe;
|
||||
wire [DATA_WIDTH-1:0] m_axis_tdata_pipe = m_axis[DATA_WIDTH-1:0];
|
||||
wire [KEEP_WIDTH-1:0] m_axis_tkeep_pipe = KEEP_ENABLE ? m_axis[KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}};
|
||||
wire m_axis_tlast_pipe = LAST_ENABLE ? m_axis[LAST_OFFSET] | m_terminate_frame_reg : 1'b1;
|
||||
wire [ID_WIDTH-1:0] m_axis_tid_pipe = ID_ENABLE ? m_axis[ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}};
|
||||
wire [DEST_WIDTH-1:0] m_axis_tdest_pipe = DEST_ENABLE ? m_axis[DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}};
|
||||
wire [USER_WIDTH-1:0] m_axis_tuser_pipe = USER_ENABLE ? (m_terminate_frame_reg ? USER_BAD_FRAME_VALUE : m_axis[USER_OFFSET +: USER_WIDTH]) : {USER_WIDTH{1'b0}};
|
||||
|
||||
assign m_axis_tdata = m_axis_tdata_pipe;
|
||||
assign m_axis_tkeep = m_axis_tkeep_pipe;
|
||||
assign m_axis_tlast = (m_terminate_frame_reg ? 1'b1 : m_axis_tlast_pipe);
|
||||
assign m_axis_tid = m_axis_tid_pipe;
|
||||
assign m_axis_tdest = m_axis_tdest_pipe;
|
||||
assign m_axis_tuser = (m_terminate_frame_reg ? USER_BAD_FRAME_VALUE : m_axis_tuser_pipe);
|
||||
wire pipe_ready;
|
||||
|
||||
assign s_status_overflow = overflow_reg;
|
||||
assign s_status_bad_frame = bad_frame_reg;
|
||||
@ -545,26 +541,26 @@ end
|
||||
integer j;
|
||||
|
||||
always @(posedge m_clk) begin
|
||||
if (m_axis_tready) begin
|
||||
if (OUTPUT_FIFO_ENABLE || m_axis_tready) begin
|
||||
// output ready; invalidate stage
|
||||
m_axis_tvalid_pipe_reg[PIPELINE_OUTPUT-1] <= 1'b0;
|
||||
m_axis_tvalid_pipe_reg[RAM_PIPELINE+1-1] <= 1'b0;
|
||||
m_terminate_frame_reg <= 1'b0;
|
||||
end
|
||||
|
||||
for (j = PIPELINE_OUTPUT-1; j > 0; j = j - 1) begin
|
||||
if (m_axis_tready || ((~m_axis_tvalid_pipe_reg) >> j)) begin
|
||||
for (j = RAM_PIPELINE+1-1; j > 0; j = j - 1) begin
|
||||
if (OUTPUT_FIFO_ENABLE || m_axis_tready || ((~m_axis_tvalid_pipe_reg) >> j)) begin
|
||||
// output ready or bubble in pipeline; transfer down pipeline
|
||||
m_axis_tvalid_pipe_reg[j] <= m_axis_tvalid_pipe_reg[j-1];
|
||||
m_axis_pipe_reg[j] <= m_axis_pipe_reg[j-1];
|
||||
m_axis_pipe_reg[j] <= j == 1 ? mem_read_data_reg : m_axis_pipe_reg[j-1];
|
||||
m_axis_tvalid_pipe_reg[j-1] <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
if (m_axis_tready || ~m_axis_tvalid_pipe_reg) begin
|
||||
if (OUTPUT_FIFO_ENABLE || m_axis_tready || ~m_axis_tvalid_pipe_reg) begin
|
||||
// output ready or bubble in pipeline; read new data from FIFO
|
||||
m_axis_tvalid_pipe_reg[0] <= 1'b0;
|
||||
m_axis_pipe_reg[0] <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]];
|
||||
if (!empty && !m_rst_sync3_reg && !m_drop_frame_reg) begin
|
||||
mem_read_data_reg <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]];
|
||||
if (!empty && !m_rst_sync3_reg && !m_drop_frame_reg && pipe_ready) begin
|
||||
// not empty, increment pointer
|
||||
m_axis_tvalid_pipe_reg[0] <= 1'b1;
|
||||
rd_ptr_temp = rd_ptr_reg + 1;
|
||||
@ -573,19 +569,19 @@ always @(posedge m_clk) begin
|
||||
end
|
||||
end
|
||||
|
||||
if (m_axis_tvalid && LAST_ENABLE) begin
|
||||
if (m_axis_tvalid_pipe && LAST_ENABLE) begin
|
||||
// track output frame status
|
||||
if (m_axis_tlast && m_axis_tready) begin
|
||||
if (m_axis_tlast_pipe && (OUTPUT_FIFO_ENABLE || m_axis_tready)) begin
|
||||
m_frame_reg <= 1'b0;
|
||||
end else begin
|
||||
m_frame_reg <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
if (m_drop_frame_reg && (m_axis_tready || !m_axis_tvalid_pipe) && LAST_ENABLE) begin
|
||||
if (m_drop_frame_reg && (OUTPUT_FIFO_ENABLE ? pipe_ready : m_axis_tready || !m_axis_tvalid_pipe) && LAST_ENABLE) begin
|
||||
// terminate frame
|
||||
// (only for frame transfers interrupted by source reset)
|
||||
m_axis_tvalid_pipe_reg[PIPELINE_OUTPUT-1] <= 1'b1;
|
||||
m_axis_tvalid_pipe_reg[RAM_PIPELINE+1-1] <= 1'b1;
|
||||
m_terminate_frame_reg <= 1'b1;
|
||||
m_drop_frame_reg <= 1'b0;
|
||||
end
|
||||
@ -594,11 +590,11 @@ always @(posedge m_clk) begin
|
||||
// if source side is reset during transfer, drop partial frame
|
||||
|
||||
// empty output pipeline, except for last stage
|
||||
if (PIPELINE_OUTPUT > 1) begin
|
||||
m_axis_tvalid_pipe_reg[PIPELINE_OUTPUT-2:0] <= 0;
|
||||
if (RAM_PIPELINE > 0) begin
|
||||
m_axis_tvalid_pipe_reg[RAM_PIPELINE+1-2:0] <= 0;
|
||||
end
|
||||
|
||||
if (m_frame_reg && (!m_axis_tvalid || (m_axis_tvalid && !m_axis_tlast)) &&
|
||||
if (m_frame_reg && (!m_axis_tvalid_pipe || (m_axis_tvalid_pipe && !m_axis_tlast_pipe)) &&
|
||||
!(m_drop_frame_reg || m_terminate_frame_reg)) begin
|
||||
// terminate frame
|
||||
m_drop_frame_reg <= 1'b1;
|
||||
@ -613,13 +609,106 @@ always @(posedge m_clk) begin
|
||||
if (m_rst) begin
|
||||
rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}};
|
||||
rd_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}};
|
||||
m_axis_tvalid_pipe_reg <= {PIPELINE_OUTPUT{1'b0}};
|
||||
m_axis_tvalid_pipe_reg <= 0;
|
||||
m_frame_reg <= 1'b0;
|
||||
m_drop_frame_reg <= 1'b0;
|
||||
m_terminate_frame_reg <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
generate
|
||||
|
||||
if (!OUTPUT_FIFO_ENABLE) begin
|
||||
|
||||
assign pipe_ready = 1'b1;
|
||||
|
||||
assign m_axis_tvalid = m_axis_tvalid_pipe;
|
||||
|
||||
assign m_axis_tdata = m_axis_tdata_pipe;
|
||||
assign m_axis_tkeep = m_axis_tkeep_pipe;
|
||||
assign m_axis_tlast = m_axis_tlast_pipe;
|
||||
assign m_axis_tid = m_axis_tid_pipe;
|
||||
assign m_axis_tdest = m_axis_tdest_pipe;
|
||||
assign m_axis_tuser = m_axis_tuser_pipe;
|
||||
|
||||
end else begin
|
||||
|
||||
// output datapath logic
|
||||
reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}};
|
||||
reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}};
|
||||
reg m_axis_tvalid_reg = 1'b0;
|
||||
reg m_axis_tlast_reg = 1'b0;
|
||||
reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}};
|
||||
reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}};
|
||||
reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}};
|
||||
|
||||
reg [OUTPUT_FIFO_ADDR_WIDTH+1-1:0] out_fifo_wr_ptr_reg = 0;
|
||||
reg [OUTPUT_FIFO_ADDR_WIDTH+1-1:0] out_fifo_rd_ptr_reg = 0;
|
||||
reg out_fifo_half_full_reg = 1'b0;
|
||||
|
||||
wire out_fifo_full = out_fifo_wr_ptr_reg == (out_fifo_rd_ptr_reg ^ {1'b1, {OUTPUT_FIFO_ADDR_WIDTH{1'b0}}});
|
||||
wire out_fifo_empty = out_fifo_wr_ptr_reg == out_fifo_rd_ptr_reg;
|
||||
|
||||
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
|
||||
reg [DATA_WIDTH-1:0] out_fifo_tdata[2**OUTPUT_FIFO_ADDR_WIDTH-1:0];
|
||||
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
|
||||
reg [KEEP_WIDTH-1:0] out_fifo_tkeep[2**OUTPUT_FIFO_ADDR_WIDTH-1:0];
|
||||
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
|
||||
reg out_fifo_tlast[2**OUTPUT_FIFO_ADDR_WIDTH-1:0];
|
||||
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
|
||||
reg [ID_WIDTH-1:0] out_fifo_tid[2**OUTPUT_FIFO_ADDR_WIDTH-1:0];
|
||||
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
|
||||
reg [DEST_WIDTH-1:0] out_fifo_tdest[2**OUTPUT_FIFO_ADDR_WIDTH-1:0];
|
||||
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
|
||||
reg [USER_WIDTH-1:0] out_fifo_tuser[2**OUTPUT_FIFO_ADDR_WIDTH-1:0];
|
||||
|
||||
assign pipe_ready = !out_fifo_half_full_reg;
|
||||
|
||||
assign m_axis_tdata = m_axis_tdata_reg;
|
||||
assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}};
|
||||
assign m_axis_tvalid = m_axis_tvalid_reg;
|
||||
assign m_axis_tlast = LAST_ENABLE ? m_axis_tlast_reg : 1'b1;
|
||||
assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}};
|
||||
assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}};
|
||||
assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}};
|
||||
|
||||
always @(posedge m_clk) begin
|
||||
m_axis_tvalid_reg <= m_axis_tvalid_reg && !m_axis_tready;
|
||||
|
||||
out_fifo_half_full_reg <= $unsigned(out_fifo_wr_ptr_reg - out_fifo_rd_ptr_reg) >= 2**(OUTPUT_FIFO_ADDR_WIDTH-1);
|
||||
|
||||
if (!out_fifo_full && m_axis_tvalid_pipe) begin
|
||||
out_fifo_tdata[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tdata_pipe;
|
||||
out_fifo_tkeep[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tkeep_pipe;
|
||||
out_fifo_tlast[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tlast_pipe;
|
||||
out_fifo_tid[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tid_pipe;
|
||||
out_fifo_tdest[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tdest_pipe;
|
||||
out_fifo_tuser[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tuser_pipe;
|
||||
out_fifo_wr_ptr_reg <= out_fifo_wr_ptr_reg + 1;
|
||||
end
|
||||
|
||||
if (!out_fifo_empty && (!m_axis_tvalid_reg || m_axis_tready)) begin
|
||||
m_axis_tdata_reg <= out_fifo_tdata[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]];
|
||||
m_axis_tkeep_reg <= out_fifo_tkeep[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]];
|
||||
m_axis_tvalid_reg <= 1'b1;
|
||||
m_axis_tlast_reg <= out_fifo_tlast[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]];
|
||||
m_axis_tid_reg <= out_fifo_tid[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]];
|
||||
m_axis_tdest_reg <= out_fifo_tdest[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]];
|
||||
m_axis_tuser_reg <= out_fifo_tuser[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]];
|
||||
out_fifo_rd_ptr_reg <= out_fifo_rd_ptr_reg + 1;
|
||||
end
|
||||
|
||||
if (m_rst) begin
|
||||
out_fifo_wr_ptr_reg <= 0;
|
||||
out_fifo_rd_ptr_reg <= 0;
|
||||
m_axis_tvalid_reg <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
`resetall
|
||||
|
@ -63,8 +63,11 @@ module axis_async_fifo_adapter #
|
||||
parameter USER_ENABLE = 1,
|
||||
// tuser signal width
|
||||
parameter USER_WIDTH = 1,
|
||||
// number of output pipeline registers
|
||||
parameter PIPELINE_OUTPUT = 2,
|
||||
// number of RAM pipeline registers in FIFO
|
||||
parameter RAM_PIPELINE = 1,
|
||||
// use output FIFO
|
||||
// When set, the RAM read enable and pipeline clock enables are removed
|
||||
parameter OUTPUT_FIFO_ENABLE = 0,
|
||||
// Frame FIFO mode - operate on frames instead of cycles
|
||||
// When set, m_axis_tvalid will not be deasserted within a frame
|
||||
// Requires LAST_ENABLE set
|
||||
@ -314,7 +317,8 @@ axis_async_fifo #(
|
||||
.DEST_WIDTH(DEST_WIDTH),
|
||||
.USER_ENABLE(USER_ENABLE),
|
||||
.USER_WIDTH(USER_WIDTH),
|
||||
.PIPELINE_OUTPUT(PIPELINE_OUTPUT),
|
||||
.RAM_PIPELINE(RAM_PIPELINE),
|
||||
.OUTPUT_FIFO_ENABLE(OUTPUT_FIFO_ENABLE),
|
||||
.FRAME_FIFO(FRAME_FIFO),
|
||||
.USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE),
|
||||
.USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK),
|
||||
|
@ -121,8 +121,8 @@ assign m_axis_tid = ID_ENABLE ? {M_COUNT{m_axis_tid_reg}} : {M_COUNT*ID_W
|
||||
assign m_axis_tdest = DEST_ENABLE ? {M_COUNT{m_axis_tdest_reg}} : {M_COUNT*DEST_WIDTH{1'b0}};
|
||||
assign m_axis_tuser = USER_ENABLE ? {M_COUNT{m_axis_tuser_reg}} : {M_COUNT*USER_WIDTH{1'b0}};
|
||||
|
||||
// enable ready input next cycle if output is ready or if both output registers are empty
|
||||
wire s_axis_tready_early = ((m_axis_tready & m_axis_tvalid) == m_axis_tvalid) || (!temp_m_axis_tvalid_reg && !m_axis_tvalid_reg);
|
||||
// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input)
|
||||
wire s_axis_tready_early = ((m_axis_tready & m_axis_tvalid) == m_axis_tvalid) || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid || !s_axis_tvalid));
|
||||
|
||||
always @* begin
|
||||
// transfer sink ready state to source
|
||||
|
@ -268,8 +268,8 @@ assign m_axis_tvalid = m_axis_tvalid_reg;
|
||||
assign m_axis_tlast = m_axis_tlast_reg;
|
||||
assign m_axis_tuser = m_axis_tuser_reg;
|
||||
|
||||
// enable ready input next cycle if output is ready or if both output registers are empty
|
||||
assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && !m_axis_tvalid_reg);
|
||||
// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input)
|
||||
assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int));
|
||||
|
||||
always @* begin
|
||||
// transfer sink ready state to source
|
||||
|
@ -445,8 +445,8 @@ assign m_axis_tvalid = m_axis_tvalid_reg;
|
||||
assign m_axis_tlast = m_axis_tlast_reg;
|
||||
assign m_axis_tuser = m_axis_tuser_reg;
|
||||
|
||||
// enable ready input next cycle if output is ready or if both output registers are empty
|
||||
assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && !m_axis_tvalid_reg);
|
||||
// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input)
|
||||
assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int));
|
||||
|
||||
always @* begin
|
||||
// transfer sink ready state to source
|
||||
|
@ -227,8 +227,8 @@ assign m_axis_tid = ID_ENABLE ? {M_COUNT{m_axis_tid_reg}} : {M_COUNT*ID_W
|
||||
assign m_axis_tdest = DEST_ENABLE ? {M_COUNT{m_axis_tdest_reg}} : {M_COUNT*M_DEST_WIDTH_INT{1'b0}};
|
||||
assign m_axis_tuser = USER_ENABLE ? {M_COUNT{m_axis_tuser_reg}} : {M_COUNT*USER_WIDTH{1'b0}};
|
||||
|
||||
// enable ready input next cycle if output is ready or if both output registers are empty
|
||||
assign m_axis_tready_int_early = (m_axis_tready & m_axis_tvalid) || (!temp_m_axis_tvalid_reg && !m_axis_tvalid_reg);
|
||||
// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input)
|
||||
assign m_axis_tready_int_early = (m_axis_tready & m_axis_tvalid) || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid || !m_axis_tvalid_int));
|
||||
|
||||
always @* begin
|
||||
// transfer sink ready state to source
|
||||
|
@ -58,8 +58,11 @@ module axis_fifo #
|
||||
parameter USER_ENABLE = 1,
|
||||
// tuser signal width
|
||||
parameter USER_WIDTH = 1,
|
||||
// number of output pipeline registers
|
||||
parameter PIPELINE_OUTPUT = 2,
|
||||
// number of RAM pipeline registers
|
||||
parameter RAM_PIPELINE = 1,
|
||||
// use output FIFO
|
||||
// When set, the RAM read enable and pipeline clock enables are removed
|
||||
parameter OUTPUT_FIFO_ENABLE = 0,
|
||||
// Frame FIFO mode - operate on frames instead of cycles
|
||||
// When set, m_axis_tvalid will not be deasserted within a frame
|
||||
// Requires LAST_ENABLE set
|
||||
@ -117,13 +120,10 @@ module axis_fifo #
|
||||
|
||||
parameter ADDR_WIDTH = (KEEP_ENABLE && KEEP_WIDTH > 1) ? $clog2(DEPTH/KEEP_WIDTH) : $clog2(DEPTH);
|
||||
|
||||
parameter OUTPUT_FIFO_ADDR_WIDTH = RAM_PIPELINE < 2 ? 3 : $clog2(RAM_PIPELINE*2+7);
|
||||
|
||||
// check configuration
|
||||
initial begin
|
||||
if (PIPELINE_OUTPUT < 1) begin
|
||||
$error("Error: PIPELINE_OUTPUT must be at least 1 (instance %m)");
|
||||
$finish;
|
||||
end
|
||||
|
||||
if (FRAME_FIFO && !LAST_ENABLE) begin
|
||||
$error("Error: FRAME_FIFO set requires LAST_ENABLE set (instance %m)");
|
||||
$finish;
|
||||
@ -166,10 +166,9 @@ reg [WIDTH-1:0] mem[(2**ADDR_WIDTH)-1:0];
|
||||
reg [WIDTH-1:0] mem_read_data_reg;
|
||||
reg mem_read_data_valid_reg = 1'b0;
|
||||
|
||||
wire [WIDTH-1:0] s_axis;
|
||||
|
||||
reg [WIDTH-1:0] m_axis_pipe_reg[PIPELINE_OUTPUT-1:0];
|
||||
reg [PIPELINE_OUTPUT-1:0] m_axis_tvalid_pipe_reg = 1'b0;
|
||||
(* shreg_extract = "no" *)
|
||||
reg [WIDTH-1:0] m_axis_pipe_reg[RAM_PIPELINE+1-1:0];
|
||||
reg [RAM_PIPELINE+1-1:0] m_axis_tvalid_pipe_reg = 0;
|
||||
|
||||
// full when first MSB different but rest same
|
||||
wire full = wr_ptr_reg == (rd_ptr_reg ^ {1'b1, {ADDR_WIDTH{1'b0}}});
|
||||
@ -187,6 +186,8 @@ reg good_frame_reg = 1'b0;
|
||||
|
||||
assign s_axis_tready = FRAME_FIFO ? (!full_cur || (full_wr && DROP_OVERSIZE_FRAME) || DROP_WHEN_FULL) : !full;
|
||||
|
||||
wire [WIDTH-1:0] s_axis;
|
||||
|
||||
generate
|
||||
assign s_axis[DATA_WIDTH-1:0] = s_axis_tdata;
|
||||
if (KEEP_ENABLE) assign s_axis[KEEP_OFFSET +: KEEP_WIDTH] = s_axis_tkeep;
|
||||
@ -196,14 +197,18 @@ generate
|
||||
if (USER_ENABLE) assign s_axis[USER_OFFSET +: USER_WIDTH] = s_axis_tuser;
|
||||
endgenerate
|
||||
|
||||
assign m_axis_tvalid = m_axis_tvalid_pipe_reg[PIPELINE_OUTPUT-1];
|
||||
wire [WIDTH-1:0] m_axis = RAM_PIPELINE ? m_axis_pipe_reg[RAM_PIPELINE+1-1] : mem_read_data_reg;
|
||||
|
||||
assign m_axis_tdata = m_axis_pipe_reg[PIPELINE_OUTPUT-1][DATA_WIDTH-1:0];
|
||||
assign m_axis_tkeep = KEEP_ENABLE ? m_axis_pipe_reg[PIPELINE_OUTPUT-1][KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}};
|
||||
assign m_axis_tlast = LAST_ENABLE ? m_axis_pipe_reg[PIPELINE_OUTPUT-1][LAST_OFFSET] : 1'b1;
|
||||
assign m_axis_tid = ID_ENABLE ? m_axis_pipe_reg[PIPELINE_OUTPUT-1][ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}};
|
||||
assign m_axis_tdest = DEST_ENABLE ? m_axis_pipe_reg[PIPELINE_OUTPUT-1][DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}};
|
||||
assign m_axis_tuser = USER_ENABLE ? m_axis_pipe_reg[PIPELINE_OUTPUT-1][USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}};
|
||||
wire m_axis_tvalid_pipe = m_axis_tvalid_pipe_reg[RAM_PIPELINE+1-1];
|
||||
|
||||
wire [DATA_WIDTH-1:0] m_axis_tdata_pipe = m_axis[DATA_WIDTH-1:0];
|
||||
wire [KEEP_WIDTH-1:0] m_axis_tkeep_pipe = KEEP_ENABLE ? m_axis[KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}};
|
||||
wire m_axis_tlast_pipe = LAST_ENABLE ? m_axis[LAST_OFFSET] : 1'b1;
|
||||
wire [ID_WIDTH-1:0] m_axis_tid_pipe = ID_ENABLE ? m_axis[ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}};
|
||||
wire [DEST_WIDTH-1:0] m_axis_tdest_pipe = DEST_ENABLE ? m_axis[DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}};
|
||||
wire [USER_WIDTH-1:0] m_axis_tuser_pipe = USER_ENABLE ? m_axis[USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}};
|
||||
|
||||
wire pipe_ready;
|
||||
|
||||
assign status_overflow = overflow_reg;
|
||||
assign status_bad_frame = bad_frame_reg;
|
||||
@ -272,25 +277,25 @@ end
|
||||
integer j;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (m_axis_tready) begin
|
||||
if (OUTPUT_FIFO_ENABLE || m_axis_tready) begin
|
||||
// output ready; invalidate stage
|
||||
m_axis_tvalid_pipe_reg[PIPELINE_OUTPUT-1] <= 1'b0;
|
||||
m_axis_tvalid_pipe_reg[RAM_PIPELINE+1-1] <= 1'b0;
|
||||
end
|
||||
|
||||
for (j = PIPELINE_OUTPUT-1; j > 0; j = j - 1) begin
|
||||
if (m_axis_tready || ((~m_axis_tvalid_pipe_reg) >> j)) begin
|
||||
for (j = RAM_PIPELINE+1-1; j > 0; j = j - 1) begin
|
||||
if (OUTPUT_FIFO_ENABLE || m_axis_tready || ((~m_axis_tvalid_pipe_reg) >> j)) begin
|
||||
// output ready or bubble in pipeline; transfer down pipeline
|
||||
m_axis_tvalid_pipe_reg[j] <= m_axis_tvalid_pipe_reg[j-1];
|
||||
m_axis_pipe_reg[j] <= m_axis_pipe_reg[j-1];
|
||||
m_axis_pipe_reg[j] <= j == 1 ? mem_read_data_reg : m_axis_pipe_reg[j-1];
|
||||
m_axis_tvalid_pipe_reg[j-1] <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
if (m_axis_tready || ~m_axis_tvalid_pipe_reg) begin
|
||||
if (OUTPUT_FIFO_ENABLE || m_axis_tready || ~m_axis_tvalid_pipe_reg) begin
|
||||
// output ready or bubble in pipeline; read new data from FIFO
|
||||
m_axis_tvalid_pipe_reg[0] <= 1'b0;
|
||||
m_axis_pipe_reg[0] <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]];
|
||||
if (!empty) begin
|
||||
mem_read_data_reg <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]];
|
||||
if (!empty && pipe_ready) begin
|
||||
// not empty, increment pointer
|
||||
m_axis_tvalid_pipe_reg[0] <= 1'b1;
|
||||
rd_ptr_reg <= rd_ptr_reg + 1;
|
||||
@ -299,10 +304,103 @@ always @(posedge clk) begin
|
||||
|
||||
if (rst) begin
|
||||
rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}};
|
||||
m_axis_tvalid_pipe_reg <= {PIPELINE_OUTPUT{1'b0}};
|
||||
m_axis_tvalid_pipe_reg <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
generate
|
||||
|
||||
if (!OUTPUT_FIFO_ENABLE) begin
|
||||
|
||||
assign pipe_ready = 1'b1;
|
||||
|
||||
assign m_axis_tvalid = m_axis_tvalid_pipe;
|
||||
|
||||
assign m_axis_tdata = m_axis_tdata_pipe;
|
||||
assign m_axis_tkeep = m_axis_tkeep_pipe;
|
||||
assign m_axis_tlast = m_axis_tlast_pipe;
|
||||
assign m_axis_tid = m_axis_tid_pipe;
|
||||
assign m_axis_tdest = m_axis_tdest_pipe;
|
||||
assign m_axis_tuser = m_axis_tuser_pipe;
|
||||
|
||||
end else begin
|
||||
|
||||
// output datapath logic
|
||||
reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}};
|
||||
reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}};
|
||||
reg m_axis_tvalid_reg = 1'b0;
|
||||
reg m_axis_tlast_reg = 1'b0;
|
||||
reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}};
|
||||
reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}};
|
||||
reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}};
|
||||
|
||||
reg [OUTPUT_FIFO_ADDR_WIDTH+1-1:0] out_fifo_wr_ptr_reg = 0;
|
||||
reg [OUTPUT_FIFO_ADDR_WIDTH+1-1:0] out_fifo_rd_ptr_reg = 0;
|
||||
reg out_fifo_half_full_reg = 1'b0;
|
||||
|
||||
wire out_fifo_full = out_fifo_wr_ptr_reg == (out_fifo_rd_ptr_reg ^ {1'b1, {OUTPUT_FIFO_ADDR_WIDTH{1'b0}}});
|
||||
wire out_fifo_empty = out_fifo_wr_ptr_reg == out_fifo_rd_ptr_reg;
|
||||
|
||||
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
|
||||
reg [DATA_WIDTH-1:0] out_fifo_tdata[2**OUTPUT_FIFO_ADDR_WIDTH-1:0];
|
||||
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
|
||||
reg [KEEP_WIDTH-1:0] out_fifo_tkeep[2**OUTPUT_FIFO_ADDR_WIDTH-1:0];
|
||||
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
|
||||
reg out_fifo_tlast[2**OUTPUT_FIFO_ADDR_WIDTH-1:0];
|
||||
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
|
||||
reg [ID_WIDTH-1:0] out_fifo_tid[2**OUTPUT_FIFO_ADDR_WIDTH-1:0];
|
||||
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
|
||||
reg [DEST_WIDTH-1:0] out_fifo_tdest[2**OUTPUT_FIFO_ADDR_WIDTH-1:0];
|
||||
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
|
||||
reg [USER_WIDTH-1:0] out_fifo_tuser[2**OUTPUT_FIFO_ADDR_WIDTH-1:0];
|
||||
|
||||
assign pipe_ready = !out_fifo_half_full_reg;
|
||||
|
||||
assign m_axis_tdata = m_axis_tdata_reg;
|
||||
assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}};
|
||||
assign m_axis_tvalid = m_axis_tvalid_reg;
|
||||
assign m_axis_tlast = LAST_ENABLE ? m_axis_tlast_reg : 1'b1;
|
||||
assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}};
|
||||
assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}};
|
||||
assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}};
|
||||
|
||||
always @(posedge clk) begin
|
||||
m_axis_tvalid_reg <= m_axis_tvalid_reg && !m_axis_tready;
|
||||
|
||||
out_fifo_half_full_reg <= $unsigned(out_fifo_wr_ptr_reg - out_fifo_rd_ptr_reg) >= 2**(OUTPUT_FIFO_ADDR_WIDTH-1);
|
||||
|
||||
if (!out_fifo_full && m_axis_tvalid_pipe) begin
|
||||
out_fifo_tdata[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tdata_pipe;
|
||||
out_fifo_tkeep[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tkeep_pipe;
|
||||
out_fifo_tlast[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tlast_pipe;
|
||||
out_fifo_tid[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tid_pipe;
|
||||
out_fifo_tdest[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tdest_pipe;
|
||||
out_fifo_tuser[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tuser_pipe;
|
||||
out_fifo_wr_ptr_reg <= out_fifo_wr_ptr_reg + 1;
|
||||
end
|
||||
|
||||
if (!out_fifo_empty && (!m_axis_tvalid_reg || m_axis_tready)) begin
|
||||
m_axis_tdata_reg <= out_fifo_tdata[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]];
|
||||
m_axis_tkeep_reg <= out_fifo_tkeep[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]];
|
||||
m_axis_tvalid_reg <= 1'b1;
|
||||
m_axis_tlast_reg <= out_fifo_tlast[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]];
|
||||
m_axis_tid_reg <= out_fifo_tid[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]];
|
||||
m_axis_tdest_reg <= out_fifo_tdest[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]];
|
||||
m_axis_tuser_reg <= out_fifo_tuser[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]];
|
||||
out_fifo_rd_ptr_reg <= out_fifo_rd_ptr_reg + 1;
|
||||
end
|
||||
|
||||
if (rst) begin
|
||||
out_fifo_wr_ptr_reg <= 0;
|
||||
out_fifo_rd_ptr_reg <= 0;
|
||||
m_axis_tvalid_reg <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
`resetall
|
||||
|
@ -63,8 +63,11 @@ module axis_fifo_adapter #
|
||||
parameter USER_ENABLE = 1,
|
||||
// tuser signal width
|
||||
parameter USER_WIDTH = 1,
|
||||
// number of output pipeline registers
|
||||
parameter PIPELINE_OUTPUT = 2,
|
||||
// number of RAM pipeline registers in FIFO
|
||||
parameter RAM_PIPELINE = 1,
|
||||
// use output FIFO
|
||||
// When set, the RAM read enable and pipeline clock enables are removed
|
||||
parameter OUTPUT_FIFO_ENABLE = 0,
|
||||
// Frame FIFO mode - operate on frames instead of cycles
|
||||
// When set, m_axis_tvalid will not be deasserted within a frame
|
||||
// Requires LAST_ENABLE set
|
||||
@ -309,7 +312,8 @@ axis_fifo #(
|
||||
.DEST_WIDTH(DEST_WIDTH),
|
||||
.USER_ENABLE(USER_ENABLE),
|
||||
.USER_WIDTH(USER_WIDTH),
|
||||
.PIPELINE_OUTPUT(PIPELINE_OUTPUT),
|
||||
.RAM_PIPELINE(RAM_PIPELINE),
|
||||
.OUTPUT_FIFO_ENABLE(OUTPUT_FIFO_ENABLE),
|
||||
.FRAME_FIFO(FRAME_FIFO),
|
||||
.USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE),
|
||||
.USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK),
|
||||
|
@ -266,8 +266,8 @@ assign m_axis_tvalid = m_axis_tvalid_reg;
|
||||
assign m_axis_tlast = m_axis_tlast_reg;
|
||||
assign m_axis_tuser = m_axis_tuser_reg;
|
||||
|
||||
// enable ready input next cycle if output is ready or if both output registers are empty
|
||||
assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && !m_axis_tvalid_reg);
|
||||
// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input)
|
||||
assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int));
|
||||
|
||||
always @* begin
|
||||
// transfer sink ready state to source
|
||||
|
@ -543,8 +543,8 @@ assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}};
|
||||
assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}};
|
||||
assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}};
|
||||
|
||||
// enable ready input next cycle if output is ready or if both output registers are empty
|
||||
assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && !m_axis_tvalid_reg);
|
||||
// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input)
|
||||
assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int));
|
||||
|
||||
always @* begin
|
||||
// transfer sink ready state to source
|
||||
|
@ -193,8 +193,8 @@ assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}};
|
||||
assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}};
|
||||
assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}};
|
||||
|
||||
// enable ready input next cycle if output is ready or if both output registers are empty
|
||||
assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && !m_axis_tvalid_reg);
|
||||
// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input)
|
||||
assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int));
|
||||
|
||||
always @* begin
|
||||
// transfer sink ready state to source
|
||||
|
@ -186,8 +186,8 @@ assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}};
|
||||
assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}};
|
||||
assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}};
|
||||
|
||||
// enable ready input next cycle if output is ready or if both output registers are empty
|
||||
assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && !m_axis_tvalid_reg);
|
||||
// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input)
|
||||
assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int));
|
||||
|
||||
always @* begin
|
||||
// transfer sink ready state to source
|
||||
|
@ -125,8 +125,8 @@ if (REG_TYPE > 1) begin
|
||||
assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}};
|
||||
assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}};
|
||||
|
||||
// enable ready input next cycle if output is ready or if both output registers are empty
|
||||
wire s_axis_tready_early = m_axis_tready || (!temp_m_axis_tvalid_reg && !m_axis_tvalid_reg);
|
||||
// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input)
|
||||
wire s_axis_tready_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !s_axis_tvalid));
|
||||
|
||||
always @* begin
|
||||
// transfer sink ready state to source
|
||||
|
@ -305,8 +305,8 @@ assign m_axis_tvalid = m_axis_tvalid_reg;
|
||||
assign m_axis_tlast = m_axis_tlast_reg;
|
||||
assign m_axis_tuser = m_axis_tuser_reg;
|
||||
|
||||
// enable ready input next cycle if output is ready or if both output registers are empty
|
||||
assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && !m_axis_tvalid_reg);
|
||||
// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input)
|
||||
assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int));
|
||||
|
||||
always @* begin
|
||||
// transfer sink ready state to source
|
||||
|
@ -258,8 +258,8 @@ assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}};
|
||||
assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}};
|
||||
assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}};
|
||||
|
||||
// enable ready input next cycle if output is ready or if both output registers are empty
|
||||
assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && !m_axis_tvalid_reg);
|
||||
// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input)
|
||||
assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int));
|
||||
|
||||
always @* begin
|
||||
// transfer sink ready state to source
|
||||
|
@ -24,8 +24,8 @@ foreach fifo_inst [get_cells -hier -filter {(ORIG_REF_NAME == axis_async_fifo ||
|
||||
puts "Inserting timing constraints for axis_async_fifo instance $fifo_inst"
|
||||
|
||||
# get clock periods
|
||||
set read_clk [get_clocks -of_objects [get_pins $fifo_inst/rd_ptr_reg_reg[0]/C]]
|
||||
set write_clk [get_clocks -of_objects [get_pins $fifo_inst/wr_ptr_reg_reg[0]/C]]
|
||||
set read_clk [get_clocks -of_objects [get_pins -quiet "$fifo_inst/rd_ptr_reg_reg[*]/C $fifo_inst/rd_ptr_gray_reg_reg[*]/C $fifo_inst/wr_ptr_gray_sync1_reg_reg[*]/C"]]
|
||||
set write_clk [get_clocks -of_objects [get_pins -quiet "$fifo_inst/wr_ptr_reg_reg[*]/C $fifo_inst/wr_ptr_gray_reg_reg[*]/C $fifo_inst/rd_ptr_gray_sync1_reg_reg[*]/C"]]
|
||||
|
||||
set read_clk_period [get_property -min PERIOD $read_clk]
|
||||
set write_clk_period [get_property -min PERIOD $write_clk]
|
||||
@ -64,15 +64,26 @@ foreach fifo_inst [get_cells -hier -filter {(ORIG_REF_NAME == axis_async_fifo ||
|
||||
}
|
||||
|
||||
# pointer synchronization
|
||||
set_property ASYNC_REG TRUE [get_cells -hier -regexp ".*/(wr|rd)_ptr_gray_sync\[12\]_reg_reg\\\[\\d+\\\]" -filter "PARENT == $fifo_inst"]
|
||||
set sync_ffs [get_cells -quiet -hier -regexp ".*/rd_ptr_gray_sync\[12\]_reg_reg\\\[\\d+\\\]" -filter "PARENT == $fifo_inst"]
|
||||
|
||||
set_max_delay -from [get_cells "$fifo_inst/rd_ptr_reg_reg[*] $fifo_inst/rd_ptr_gray_reg_reg[*]"] -to [get_cells $fifo_inst/rd_ptr_gray_sync1_reg_reg[*]] -datapath_only $read_clk_period
|
||||
set_bus_skew -from [get_cells "$fifo_inst/rd_ptr_reg_reg[*] $fifo_inst/rd_ptr_gray_reg_reg[*]"] -to [get_cells $fifo_inst/rd_ptr_gray_sync1_reg_reg[*]] $write_clk_period
|
||||
set_max_delay -from [get_cells -quiet "$fifo_inst/wr_ptr_reg_reg[*] $fifo_inst/wr_ptr_gray_reg_reg[*] $fifo_inst/wr_ptr_sync_gray_reg_reg[*]"] -to [get_cells $fifo_inst/wr_ptr_gray_sync1_reg_reg[*]] -datapath_only $write_clk_period
|
||||
set_bus_skew -from [get_cells -quiet "$fifo_inst/wr_ptr_reg_reg[*] $fifo_inst/wr_ptr_gray_reg_reg[*] $fifo_inst/wr_ptr_sync_gray_reg_reg[*]"] -to [get_cells $fifo_inst/wr_ptr_gray_sync1_reg_reg[*]] $read_clk_period
|
||||
if {[llength $sync_ffs]} {
|
||||
set_property ASYNC_REG TRUE $sync_ffs
|
||||
|
||||
set_max_delay -from [get_cells "$fifo_inst/rd_ptr_reg_reg[*] $fifo_inst/rd_ptr_gray_reg_reg[*]"] -to [get_cells "$fifo_inst/rd_ptr_gray_sync1_reg_reg[*]"] -datapath_only $read_clk_period
|
||||
set_bus_skew -from [get_cells "$fifo_inst/rd_ptr_reg_reg[*] $fifo_inst/rd_ptr_gray_reg_reg[*]"] -to [get_cells "$fifo_inst/rd_ptr_gray_sync1_reg_reg[*]"] $write_clk_period
|
||||
}
|
||||
|
||||
set sync_ffs [get_cells -quiet -hier -regexp ".*/wr_ptr_gray_sync\[12\]_reg_reg\\\[\\d+\\\]" -filter "PARENT == $fifo_inst"]
|
||||
|
||||
if {[llength $sync_ffs]} {
|
||||
set_property ASYNC_REG TRUE $sync_ffs
|
||||
|
||||
set_max_delay -from [get_cells -quiet "$fifo_inst/wr_ptr_reg_reg[*] $fifo_inst/wr_ptr_gray_reg_reg[*] $fifo_inst/wr_ptr_sync_gray_reg_reg[*]"] -to [get_cells "$fifo_inst/wr_ptr_gray_sync1_reg_reg[*]"] -datapath_only $write_clk_period
|
||||
set_bus_skew -from [get_cells -quiet "$fifo_inst/wr_ptr_reg_reg[*] $fifo_inst/wr_ptr_gray_reg_reg[*] $fifo_inst/wr_ptr_sync_gray_reg_reg[*]"] -to [get_cells "$fifo_inst/wr_ptr_gray_sync1_reg_reg[*]"] $read_clk_period
|
||||
}
|
||||
|
||||
# output register (needed for distributed RAM sync write/async read)
|
||||
set output_reg_ffs [get_cells -quiet "$fifo_inst/m_axis_pipe_reg_reg[0][*]"]
|
||||
set output_reg_ffs [get_cells -quiet "$fifo_inst/mem_read_data_reg_reg[*]"]
|
||||
|
||||
if {[llength $output_reg_ffs]} {
|
||||
set_false_path -from $write_clk -to $output_reg_ffs
|
||||
@ -84,8 +95,8 @@ foreach fifo_inst [get_cells -hier -filter {(ORIG_REF_NAME == axis_async_fifo ||
|
||||
if {[llength $update_ffs]} {
|
||||
set_property ASYNC_REG TRUE $update_ffs
|
||||
|
||||
set_max_delay -from [get_cells $fifo_inst/wr_ptr_update_reg_reg] -to [get_cells $fifo_inst/wr_ptr_update_sync1_reg_reg] -datapath_only $write_clk_period
|
||||
set_max_delay -from [get_cells $fifo_inst/wr_ptr_update_sync3_reg_reg] -to [get_cells $fifo_inst/wr_ptr_update_ack_sync1_reg_reg] -datapath_only $read_clk_period
|
||||
set_max_delay -from [get_cells "$fifo_inst/wr_ptr_update_reg_reg"] -to [get_cells "$fifo_inst/wr_ptr_update_sync1_reg_reg"] -datapath_only $write_clk_period
|
||||
set_max_delay -from [get_cells "$fifo_inst/wr_ptr_update_sync3_reg_reg"] -to [get_cells "$fifo_inst/wr_ptr_update_ack_sync1_reg_reg"] -datapath_only $read_clk_period
|
||||
}
|
||||
|
||||
# status synchronization
|
||||
@ -95,7 +106,7 @@ foreach fifo_inst [get_cells -hier -filter {(ORIG_REF_NAME == axis_async_fifo ||
|
||||
if {[llength $status_sync_regs]} {
|
||||
set_property ASYNC_REG TRUE $status_sync_regs
|
||||
|
||||
set_max_delay -from [get_cells $fifo_inst/${i}_sync1_reg_reg] -to [get_cells $fifo_inst/${i}_sync2_reg_reg] -datapath_only $read_clk_period
|
||||
set_max_delay -from [get_cells "$fifo_inst/${i}_sync1_reg_reg"] -to [get_cells "$fifo_inst/${i}_sync2_reg_reg"] -datapath_only $read_clk_period
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,8 @@ export PARAM_DEST_ENABLE ?= 1
|
||||
export PARAM_DEST_WIDTH ?= 8
|
||||
export PARAM_USER_ENABLE ?= 1
|
||||
export PARAM_USER_WIDTH ?= 1
|
||||
export PARAM_PIPELINE_OUTPUT ?= 2
|
||||
export PARAM_RAM_PIPELINE ?= 1
|
||||
export PARAM_OUTPUT_FIFO_ENABLE ?= 0
|
||||
export PARAM_FRAME_FIFO ?= 1
|
||||
export PARAM_USER_BAD_FRAME_VALUE ?= 1
|
||||
export PARAM_USER_BAD_FRAME_MASK ?= 1
|
||||
@ -65,7 +66,8 @@ ifeq ($(SIM), icarus)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).DEST_WIDTH=$(PARAM_DEST_WIDTH)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_ENABLE=$(PARAM_USER_ENABLE)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_WIDTH=$(PARAM_USER_WIDTH)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).PIPELINE_OUTPUT=$(PARAM_PIPELINE_OUTPUT)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).RAM_PIPELINE=$(PARAM_RAM_PIPELINE)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).OUTPUT_FIFO_ENABLE=$(PARAM_OUTPUT_FIFO_ENABLE)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).FRAME_FIFO=$(PARAM_FRAME_FIFO)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_BAD_FRAME_VALUE=$(PARAM_USER_BAD_FRAME_VALUE)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_BAD_FRAME_MASK=$(PARAM_USER_BAD_FRAME_MASK)
|
||||
@ -91,7 +93,8 @@ else ifeq ($(SIM), verilator)
|
||||
COMPILE_ARGS += -GDEST_WIDTH=$(PARAM_DEST_WIDTH)
|
||||
COMPILE_ARGS += -GUSER_ENABLE=$(PARAM_USER_ENABLE)
|
||||
COMPILE_ARGS += -GUSER_WIDTH=$(PARAM_USER_WIDTH)
|
||||
COMPILE_ARGS += -GPIPELINE_OUTPUT=$(PARAM_PIPELINE_OUTPUT)
|
||||
COMPILE_ARGS += -GRAM_PIPELINE=$(PARAM_RAM_PIPELINE)
|
||||
COMPILE_ARGS += -GOUTPUT_FIFO_ENABLE=$(PARAM_OUTPUT_FIFO_ENABLE)
|
||||
COMPILE_ARGS += -GFRAME_FIFO=$(PARAM_FRAME_FIFO)
|
||||
COMPILE_ARGS += -GUSER_BAD_FRAME_VALUE=$(PARAM_USER_BAD_FRAME_VALUE)
|
||||
COMPILE_ARGS += -GUSER_BAD_FRAME_MASK=$(PARAM_USER_BAD_FRAME_MASK)
|
||||
|
@ -229,11 +229,11 @@ async def run_test_init_sink_pause_source_reset(dut):
|
||||
|
||||
tb.sink.pause = True
|
||||
|
||||
test_data = bytearray(itertools.islice(itertools.cycle(range(256)), 32))
|
||||
test_data = bytearray(itertools.islice(itertools.cycle(range(256)), 512))
|
||||
test_frame = AxiStreamFrame(test_data)
|
||||
await tb.source.send(test_frame)
|
||||
|
||||
for k in range(64):
|
||||
for k in range(1024):
|
||||
await RisingEdge(dut.s_clk)
|
||||
|
||||
await tb.reset_source()
|
||||
@ -522,9 +522,11 @@ rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl'))
|
||||
@pytest.mark.parametrize(("s_clk", "m_clk"), [(10, 10), (10, 11), (11, 10)])
|
||||
@pytest.mark.parametrize(("frame_fifo", "drop_oversize_frame", "drop_bad_frame", "drop_when_full"),
|
||||
[(0, 0, 0, 0), (1, 0, 0, 0), (1, 1, 0, 0), (1, 1, 1, 0)])
|
||||
@pytest.mark.parametrize(("ram_pipeline", "output_fifo"),
|
||||
[(0, 0), (1, 0), (4, 0), (0, 1), (1, 1), (4, 1)])
|
||||
@pytest.mark.parametrize("data_width", [8, 16, 32, 64])
|
||||
def test_axis_async_fifo(request, data_width, frame_fifo, drop_oversize_frame, drop_bad_frame,
|
||||
drop_when_full, s_clk, m_clk):
|
||||
def test_axis_async_fifo(request, data_width, ram_pipeline, output_fifo,
|
||||
frame_fifo, drop_oversize_frame, drop_bad_frame, drop_when_full, s_clk, m_clk):
|
||||
|
||||
dut = "axis_async_fifo"
|
||||
module = os.path.splitext(os.path.basename(__file__))[0]
|
||||
@ -547,7 +549,8 @@ def test_axis_async_fifo(request, data_width, frame_fifo, drop_oversize_frame, d
|
||||
parameters['DEST_WIDTH'] = 8
|
||||
parameters['USER_ENABLE'] = 1
|
||||
parameters['USER_WIDTH'] = 1
|
||||
parameters['PIPELINE_OUTPUT'] = 2
|
||||
parameters['RAM_PIPELINE'] = ram_pipeline
|
||||
parameters['OUTPUT_FIFO_ENABLE'] = output_fifo
|
||||
parameters['FRAME_FIFO'] = frame_fifo
|
||||
parameters['USER_BAD_FRAME_VALUE'] = 1
|
||||
parameters['USER_BAD_FRAME_MASK'] = 1
|
||||
|
@ -48,6 +48,8 @@ export PARAM_DEST_ENABLE ?= 1
|
||||
export PARAM_DEST_WIDTH ?= 8
|
||||
export PARAM_USER_ENABLE ?= 1
|
||||
export PARAM_USER_WIDTH ?= 1
|
||||
export PARAM_RAM_PIPELINE ?= 1
|
||||
export PARAM_OUTPUT_FIFO_ENABLE ?= 0
|
||||
export PARAM_FRAME_FIFO ?= 1
|
||||
export PARAM_USER_BAD_FRAME_VALUE ?= 1
|
||||
export PARAM_USER_BAD_FRAME_MASK ?= 1
|
||||
@ -71,6 +73,8 @@ ifeq ($(SIM), icarus)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).DEST_WIDTH=$(PARAM_DEST_WIDTH)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_ENABLE=$(PARAM_USER_ENABLE)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_WIDTH=$(PARAM_USER_WIDTH)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).RAM_PIPELINE=$(PARAM_RAM_PIPELINE)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).OUTPUT_FIFO_ENABLE=$(PARAM_OUTPUT_FIFO_ENABLE)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).FRAME_FIFO=$(PARAM_FRAME_FIFO)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_BAD_FRAME_VALUE=$(PARAM_USER_BAD_FRAME_VALUE)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_BAD_FRAME_MASK=$(PARAM_USER_BAD_FRAME_MASK)
|
||||
@ -98,6 +102,8 @@ else ifeq ($(SIM), verilator)
|
||||
COMPILE_ARGS += -GDEST_WIDTH=$(PARAM_DEST_WIDTH)
|
||||
COMPILE_ARGS += -GUSER_ENABLE=$(PARAM_USER_ENABLE)
|
||||
COMPILE_ARGS += -GUSER_WIDTH=$(PARAM_USER_WIDTH)
|
||||
COMPILE_ARGS += -GRAM_PIPELINE=$(PARAM_RAM_PIPELINE)
|
||||
COMPILE_ARGS += -GOUTPUT_FIFO_ENABLE=$(PARAM_OUTPUT_FIFO_ENABLE)
|
||||
COMPILE_ARGS += -GFRAME_FIFO=$(PARAM_FRAME_FIFO)
|
||||
COMPILE_ARGS += -GUSER_BAD_FRAME_VALUE=$(PARAM_USER_BAD_FRAME_VALUE)
|
||||
COMPILE_ARGS += -GUSER_BAD_FRAME_MASK=$(PARAM_USER_BAD_FRAME_MASK)
|
||||
|
@ -546,6 +546,8 @@ def test_axis_async_fifo_adapter(request, s_data_width, m_data_width, frame_fifo
|
||||
parameters['DEST_WIDTH'] = 8
|
||||
parameters['USER_ENABLE'] = 1
|
||||
parameters['USER_WIDTH'] = 1
|
||||
parameters['RAM_PIPELINE'] = 1
|
||||
parameters['OUTPUT_FIFO_ENABLE'] = 0
|
||||
parameters['FRAME_FIFO'] = frame_fifo
|
||||
parameters['USER_BAD_FRAME_VALUE'] = 1
|
||||
parameters['USER_BAD_FRAME_MASK'] = 1
|
||||
|
@ -43,7 +43,8 @@ export PARAM_DEST_ENABLE ?= 1
|
||||
export PARAM_DEST_WIDTH ?= 8
|
||||
export PARAM_USER_ENABLE ?= 1
|
||||
export PARAM_USER_WIDTH ?= 1
|
||||
export PARAM_PIPELINE_OUTPUT ?= 2
|
||||
export PARAM_RAM_PIPELINE ?= 1
|
||||
export PARAM_OUTPUT_FIFO_ENABLE ?= 0
|
||||
export PARAM_FRAME_FIFO ?= 1
|
||||
export PARAM_USER_BAD_FRAME_VALUE ?= 1
|
||||
export PARAM_USER_BAD_FRAME_MASK ?= 1
|
||||
@ -65,7 +66,8 @@ ifeq ($(SIM), icarus)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).DEST_WIDTH=$(PARAM_DEST_WIDTH)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_ENABLE=$(PARAM_USER_ENABLE)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_WIDTH=$(PARAM_USER_WIDTH)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).PIPELINE_OUTPUT=$(PARAM_PIPELINE_OUTPUT)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).RAM_PIPELINE=$(PARAM_RAM_PIPELINE)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).OUTPUT_FIFO_ENABLE=$(PARAM_OUTPUT_FIFO_ENABLE)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).FRAME_FIFO=$(PARAM_FRAME_FIFO)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_BAD_FRAME_VALUE=$(PARAM_USER_BAD_FRAME_VALUE)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_BAD_FRAME_MASK=$(PARAM_USER_BAD_FRAME_MASK)
|
||||
@ -91,7 +93,8 @@ else ifeq ($(SIM), verilator)
|
||||
COMPILE_ARGS += -GDEST_WIDTH=$(PARAM_DEST_WIDTH)
|
||||
COMPILE_ARGS += -GUSER_ENABLE=$(PARAM_USER_ENABLE)
|
||||
COMPILE_ARGS += -GUSER_WIDTH=$(PARAM_USER_WIDTH)
|
||||
COMPILE_ARGS += -GPIPELINE_OUTPUT=$(PARAM_PIPELINE_OUTPUT)
|
||||
COMPILE_ARGS += -GRAM_PIPELINE=$(PARAM_RAM_PIPELINE)
|
||||
COMPILE_ARGS += -GOUTPUT_FIFO_ENABLE=$(PARAM_OUTPUT_FIFO_ENABLE)
|
||||
COMPILE_ARGS += -GFRAME_FIFO=$(PARAM_FRAME_FIFO)
|
||||
COMPILE_ARGS += -GUSER_BAD_FRAME_VALUE=$(PARAM_USER_BAD_FRAME_VALUE)
|
||||
COMPILE_ARGS += -GUSER_BAD_FRAME_MASK=$(PARAM_USER_BAD_FRAME_MASK)
|
||||
|
@ -314,8 +314,12 @@ rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl'))
|
||||
|
||||
@pytest.mark.parametrize(("frame_fifo", "drop_oversize_frame", "drop_bad_frame", "drop_when_full"),
|
||||
[(0, 0, 0, 0), (1, 0, 0, 0), (1, 1, 0, 0), (1, 1, 1, 0)])
|
||||
@pytest.mark.parametrize(("ram_pipeline", "output_fifo"),
|
||||
[(0, 0), (1, 0), (4, 0), (0, 1), (1, 1), (4, 1)])
|
||||
@pytest.mark.parametrize("data_width", [8, 16, 32, 64])
|
||||
def test_axis_fifo(request, data_width, frame_fifo, drop_oversize_frame, drop_bad_frame, drop_when_full):
|
||||
def test_axis_fifo(request, data_width, ram_pipeline, output_fifo,
|
||||
frame_fifo, drop_oversize_frame, drop_bad_frame, drop_when_full):
|
||||
|
||||
dut = "axis_fifo"
|
||||
module = os.path.splitext(os.path.basename(__file__))[0]
|
||||
toplevel = dut
|
||||
@ -337,7 +341,8 @@ def test_axis_fifo(request, data_width, frame_fifo, drop_oversize_frame, drop_ba
|
||||
parameters['DEST_WIDTH'] = 8
|
||||
parameters['USER_ENABLE'] = 1
|
||||
parameters['USER_WIDTH'] = 1
|
||||
parameters['PIPELINE_OUTPUT'] = 2
|
||||
parameters['RAM_PIPELINE'] = ram_pipeline
|
||||
parameters['OUTPUT_FIFO_ENABLE'] = output_fifo
|
||||
parameters['FRAME_FIFO'] = frame_fifo
|
||||
parameters['USER_BAD_FRAME_VALUE'] = 1
|
||||
parameters['USER_BAD_FRAME_MASK'] = 1
|
||||
|
@ -48,6 +48,8 @@ export PARAM_DEST_ENABLE ?= 1
|
||||
export PARAM_DEST_WIDTH ?= 8
|
||||
export PARAM_USER_ENABLE ?= 1
|
||||
export PARAM_USER_WIDTH ?= 1
|
||||
export PARAM_RAM_PIPELINE ?= 1
|
||||
export PARAM_OUTPUT_FIFO_ENABLE ?= 0
|
||||
export PARAM_FRAME_FIFO ?= 1
|
||||
export PARAM_USER_BAD_FRAME_VALUE ?= 1
|
||||
export PARAM_USER_BAD_FRAME_MASK ?= 1
|
||||
@ -71,6 +73,8 @@ ifeq ($(SIM), icarus)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).DEST_WIDTH=$(PARAM_DEST_WIDTH)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_ENABLE=$(PARAM_USER_ENABLE)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_WIDTH=$(PARAM_USER_WIDTH)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).RAM_PIPELINE=$(PARAM_RAM_PIPELINE)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).OUTPUT_FIFO_ENABLE=$(PARAM_OUTPUT_FIFO_ENABLE)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).FRAME_FIFO=$(PARAM_FRAME_FIFO)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_BAD_FRAME_VALUE=$(PARAM_USER_BAD_FRAME_VALUE)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_BAD_FRAME_MASK=$(PARAM_USER_BAD_FRAME_MASK)
|
||||
@ -98,6 +102,8 @@ else ifeq ($(SIM), verilator)
|
||||
COMPILE_ARGS += -GDEST_WIDTH=$(PARAM_DEST_WIDTH)
|
||||
COMPILE_ARGS += -GUSER_ENABLE=$(PARAM_USER_ENABLE)
|
||||
COMPILE_ARGS += -GUSER_WIDTH=$(PARAM_USER_WIDTH)
|
||||
COMPILE_ARGS += -GRAM_PIPELINE=$(PARAM_RAM_PIPELINE)
|
||||
COMPILE_ARGS += -GOUTPUT_FIFO_ENABLE=$(PARAM_OUTPUT_FIFO_ENABLE)
|
||||
COMPILE_ARGS += -GFRAME_FIFO=$(PARAM_FRAME_FIFO)
|
||||
COMPILE_ARGS += -GUSER_BAD_FRAME_VALUE=$(PARAM_USER_BAD_FRAME_VALUE)
|
||||
COMPILE_ARGS += -GUSER_BAD_FRAME_MASK=$(PARAM_USER_BAD_FRAME_MASK)
|
||||
|
@ -342,6 +342,8 @@ def test_axis_fifo_adapter(request, s_data_width, m_data_width, frame_fifo, drop
|
||||
parameters['DEST_WIDTH'] = 8
|
||||
parameters['USER_ENABLE'] = 1
|
||||
parameters['USER_WIDTH'] = 1
|
||||
parameters['RAM_PIPELINE'] = 1
|
||||
parameters['OUTPUT_FIFO_ENABLE'] = 0
|
||||
parameters['FRAME_FIFO'] = frame_fifo
|
||||
parameters['USER_BAD_FRAME_VALUE'] = 1
|
||||
parameters['USER_BAD_FRAME_MASK'] = 1
|
||||
|
@ -11,13 +11,14 @@ python =
|
||||
|
||||
[testenv]
|
||||
deps =
|
||||
pytest == 6.2.5
|
||||
pytest-xdist == 2.4.0
|
||||
pytest-split == 0.4.0
|
||||
cocotb == 1.6.1
|
||||
cocotb-test == 0.2.1
|
||||
cocotbext-axi == 0.1.16
|
||||
jinja2 == 3.0.3
|
||||
pytest == 7.1.3
|
||||
pytest-xdist == 2.5.0
|
||||
pytest-split == 0.8.0
|
||||
cocotb == 1.7.0
|
||||
cocotb-bus == 0.2.1
|
||||
cocotb-test == 0.2.2
|
||||
cocotbext-axi == 0.1.18
|
||||
jinja2 == 3.1.2
|
||||
|
||||
commands =
|
||||
pytest -n auto {posargs}
|
||||
|
Loading…
x
Reference in New Issue
Block a user