📄 rx_client_fifo.v
字号:
end
always @(posedge read_clock_in)
begin
if (ll_reset == 1'b1)
frame_count <= 9'd0;
else
begin
if (frame_transmitted_pulse == 1'b1 && ll_frame_received == 1'b0)
frame_count <= frame_count - 1;
else if (frame_transmitted_pulse == 1'b0 && ll_frame_received == 1'b1)
frame_count <= frame_count + 1;
end
end
// **If the FIFO is expanded to use more BRAM, ensure frame count signals are
// wide enough to count the maximum number of frames that can be stored in FIFO**
assign frame_in_fifo = (frame_count == 9'd0) ? 1'b0 : 1'b1;
//---------------------------------------------------------------------------
// Hold the frame_in_fifo signal until the frame has actually been
// transmitted. This will be used to gate the data_valid output.
//---------------------------------------------------------------------------
always @(posedge read_clock_in)
begin
if (ll_reset == 1'b1)
frame_in_fifo_held <= 1'b0;
else if ((frame_in_progress == 1'b1 && read_data_valid_int == 1'b0) | frame_in_fifo == 1'b1)
frame_in_fifo_held <= frame_in_fifo;
end
//--------------------------------------------------------------------
// Generate a signal to indicate when the fifo is in the process of
// transmitting a frame.
//--------------------------------------------------------------------
always @(posedge read_clock_in)
begin
if (ll_reset == 1'b1)
frame_in_progress <= 1'b0;
else if ((dst_rdy_in_n == 1'b0 && read_data_valid_pipe[0] == 1'b0) || frame_in_fifo_held == 1'b0)
frame_in_progress <= 1'b0;
else if (frame_transmitted == 1'b1)
frame_in_progress <= 1'b1;
end
//--------------------------------------------------------------------
// At the start of each frame we need to clock the first byte of
// data from the memory as we have to change this as soon as ack is
// received.
//--------------------------------------------------------------------
assign queue = frame_in_fifo & !read_data_valid_pipe[0];
//--------------------------------------------------------------------
// We have to calculate the occupancy of the fifo as we need to drop
// frames when it is about to overflow. This will be calculated on
// the rx clock and so we need to get the read_addr into the rx clock
// domain. To do this we first convert the tx_addr to gray codes as
// this helps to counter problems with the 2 addresses being on
// different clock domains. This gray code representation of the
// read_addr is then clocked onto the rx_clk and converted back to
// binary. The binary version can then be compared to to the
// rx_addr on the rx_clk.
// **If the FIFO is expanded to use more BRAM, increase read_addr_gray,
// rx_read_addr_gray and rx_read_addr_bin size as required **
//--------------------------------------------------------------------
// Convert read address to gray codes.
always @(posedge read_clock_in)
begin
if (ll_reset == 1'b1)
read_addr_gray <= 12'h001;
else
begin
read_addr_gray[11] <= read_addr_reg[11];
read_addr_gray[10] <= read_addr_reg[11] ^ read_addr_reg[10];
read_addr_gray[9] <= read_addr_reg[10] ^ read_addr_reg[9];
read_addr_gray[8] <= read_addr_reg[9] ^ read_addr_reg[8];
read_addr_gray[7] <= read_addr_reg[8] ^ read_addr_reg[7];
read_addr_gray[6] <= read_addr_reg[7] ^ read_addr_reg[6];
read_addr_gray[5] <= read_addr_reg[6] ^ read_addr_reg[5];
read_addr_gray[4] <= read_addr_reg[5] ^ read_addr_reg[4];
read_addr_gray[3] <= read_addr_reg[4] ^ read_addr_reg[3];
read_addr_gray[2] <= read_addr_reg[3] ^ read_addr_reg[2];
read_addr_gray[1] <= read_addr_reg[2] ^ read_addr_reg[1];
read_addr_gray[0] <= read_addr_reg[1] ^ read_addr_reg[0];
end
end
// Clock this onto the rx_clk.
always @(posedge rx_clk)
begin
if (rx_reset == 1'b1)
rx_read_addr_gray <= 12'h000;
else if (rx_enable == 1'b1)
rx_read_addr_gray <= read_addr_gray;
end
// Convert this back to binary.
always @(posedge rx_clk)
begin
if (rx_reset == 1'b1)
rx_read_addr_bin <= 12'h000;
else if (rx_enable == 1'b1)
begin
rx_read_addr_bin[11] <= rx_read_addr_gray[11];
rx_read_addr_bin[10] <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10];
rx_read_addr_bin[9] <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10]
^ rx_read_addr_gray[9];
rx_read_addr_bin[8] <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10]
^ rx_read_addr_gray[9] ^ rx_read_addr_gray[8];
rx_read_addr_bin[7] <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10]
^ rx_read_addr_gray[9] ^ rx_read_addr_gray[8]
^ rx_read_addr_gray[7];
rx_read_addr_bin[6] <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10]
^ rx_read_addr_gray[9] ^ rx_read_addr_gray[8]
^ rx_read_addr_gray[7] ^ rx_read_addr_gray[6];
rx_read_addr_bin[5] <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10]
^ rx_read_addr_gray[9] ^ rx_read_addr_gray[8]
^ rx_read_addr_gray[7] ^ rx_read_addr_gray[6]
^ rx_read_addr_gray[5];
rx_read_addr_bin[4] <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10]
^ rx_read_addr_gray[9] ^ rx_read_addr_gray[8]
^ rx_read_addr_gray[7] ^ rx_read_addr_gray[6]
^ rx_read_addr_gray[5] ^ rx_read_addr_gray[4];
rx_read_addr_bin[3] <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10]
^ rx_read_addr_gray[9] ^ rx_read_addr_gray[8]
^ rx_read_addr_gray[7] ^ rx_read_addr_gray[6]
^ rx_read_addr_gray[5] ^ rx_read_addr_gray[4]
^ rx_read_addr_gray[3];
rx_read_addr_bin[2] <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10]
^ rx_read_addr_gray[9] ^ rx_read_addr_gray[8]
^ rx_read_addr_gray[7] ^ rx_read_addr_gray[6]
^ rx_read_addr_gray[5] ^ rx_read_addr_gray[4]
^ rx_read_addr_gray[3] ^ rx_read_addr_gray[2];
rx_read_addr_bin[1] <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10]
^ rx_read_addr_gray[9] ^ rx_read_addr_gray[8]
^ rx_read_addr_gray[7] ^ rx_read_addr_gray[6]
^ rx_read_addr_gray[5] ^ rx_read_addr_gray[4]
^ rx_read_addr_gray[3] ^ rx_read_addr_gray[2]
^ rx_read_addr_gray[1];
rx_read_addr_bin[0] <= rx_read_addr_gray[11] ^ rx_read_addr_gray[10]
^ rx_read_addr_gray[9] ^ rx_read_addr_gray[8]
^ rx_read_addr_gray[7] ^ rx_read_addr_gray[6]
^ rx_read_addr_gray[5] ^ rx_read_addr_gray[4]
^ rx_read_addr_gray[3] ^ rx_read_addr_gray[2]
^ rx_read_addr_gray[1] ^ rx_read_addr_gray[0];
end
end
// Set the full flag to go up when the rx address is 16 bytes
// away from the tx address.
always @(posedge rx_clk)
begin
if (rx_reset == 1'b1)
rx_addr_sub <= 12'h000;
else if (rx_enable == 1'b1)
rx_addr_sub <= rx_read_addr_bin - rx_addr_reg;
end
assign full_pulse = (rx_addr_sub < 12'd16 && rx_addr_sub > 12'd1) ? 1'b1 : 1'b0;
//---------------------------------------------------------------------------
// Fifo status indicates the amount of memory space used.
// This needs to be calculated on the read clock domain and so rx_addr must
// be converted to the read clock domain via gray code.
// **If the FIFO is expanded to use more BRAM, increase rx_addr_gray,
// ll_rx_addr_gray and ll_rx_addr_bin size as required **
//---------------------------------------------------------------------------
// Convert the rx address to gray codes.
always @(posedge rx_clk)
begin
if (rx_reset == 1'b1)
rx_addr_gray <= 12'h000;
else if (rx_enable == 1'b1)
begin
rx_addr_gray[11] <= rx_addr_reg[11];
rx_addr_gray[10] <= rx_addr_reg[11] ^ rx_addr_reg[10];
rx_addr_gray[9] <= rx_addr_reg[10] ^ rx_addr_reg[9];
rx_addr_gray[8] <= rx_addr_reg[9] ^ rx_addr_reg[8];
rx_addr_gray[7] <= rx_addr_reg[8] ^ rx_addr_reg[7];
rx_addr_gray[6] <= rx_addr_reg[7] ^ rx_addr_reg[6];
rx_addr_gray[5] <= rx_addr_reg[6] ^ rx_addr_reg[5];
rx_addr_gray[4] <= rx_addr_reg[5] ^ rx_addr_reg[4];
rx_addr_gray[3] <= rx_addr_reg[4] ^ rx_addr_reg[3];
rx_addr_gray[2] <= rx_addr_reg[3] ^ rx_addr_reg[2];
rx_addr_gray[1] <= rx_addr_reg[2] ^ rx_addr_reg[1];
rx_addr_gray[0] <= rx_addr_reg[1] ^ rx_addr_reg[0];
end
end
// Clock this onto the read clock.
always @(posedge read_clock_in)
begin
if (ll_reset == 1'b1)
ll_rx_addr_gray <= 12'h000;
else
ll_rx_addr_gray <= rx_addr_gray;
end
// Convert this back to binary.
always @(posedge read_clock_in)
begin
if (ll_reset == 1'b1)
ll_rx_addr_bin <= 12'h000;
else
begin
ll_rx_addr_bin[11] <= ll_rx_addr_gray[11];
ll_rx_addr_bin[10] <= ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10];
ll_rx_addr_bin[9] <= ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10]
^ ll_rx_addr_gray[9];
ll_rx_addr_bin[8] <= ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10]
^ ll_rx_addr_gray[9] ^ ll_rx_addr_gray[8];
ll_rx_addr_bin[7] <= ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10]
^ ll_rx_addr_gray[9] ^ ll_rx_addr_gray[8]
^ ll_rx_addr_gray[7];
ll_rx_addr_bin[6] <= ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10]
^ ll_rx_addr_gray[9] ^ ll_rx_addr_gray[8]
^ ll_rx_addr_gray[7] ^ ll_rx_addr_gray[6];
ll_rx_addr_bin[5] <= ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10]
^ ll_rx_addr_gray[9] ^ ll_rx_addr_gray[8]
^ ll_rx_addr_gray[7] ^ ll_rx_addr_gray[6]
^ ll_rx_addr_gray[5];
ll_rx_addr_bin[4] <= ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10]
^ ll_rx_addr_gray[9] ^ ll_rx_addr_gray[8]
^ ll_rx_addr_gray[7] ^ ll_rx_addr_gray[6]
^ ll_rx_addr_gray[5] ^ ll_rx_addr_gray[4];
ll_rx_addr_bin[3] <= ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10]
^ ll_rx_addr_gray[9] ^ ll_rx_addr_gray[8]
^ ll_rx_addr_gray[7] ^ ll_rx_addr_gray[6]
^ ll_rx_addr_gray[5] ^ ll_rx_addr_gray[4]
^ ll_rx_addr_gray[3];
ll_rx_addr_bin[2] <= ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10]
^ ll_rx_addr_gray[9] ^ ll_rx_addr_gray[8]
^ ll_rx_addr_gray[7] ^ ll_rx_addr_gray[6]
^ ll_rx_addr_gray[5] ^ ll_rx_addr_gray[4]
^ ll_rx_addr_gray[3] ^ ll_rx_addr_gray[2];
ll_rx_addr_bin[1] <= ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10]
^ ll_rx_addr_gray[9] ^ ll_rx_addr_gray[8]
^ ll_rx_addr_gray[7] ^ ll_rx_addr_gray[6]
^ ll_rx_addr_gray[5] ^ ll_rx_addr_gray[4]
^ ll_rx_addr_gray[3] ^ ll_rx_addr_gray[2]
^ ll_rx_addr_gray[1];
ll_rx_addr_bin[0] <= ll_rx_addr_gray[11] ^ ll_rx_addr_gray[10]
^ ll_rx_addr_gray[9] ^ ll_rx_addr_gray[8]
^ ll_rx_addr_gray[7] ^ ll_rx_addr_gray[6]
^ ll_rx_addr_gray[5] ^ ll_rx_addr_gray[4]
^ ll_rx_addr_gray[3] ^ ll_rx_addr_gray[2]
^ ll_rx_addr_gray[1] ^ ll_rx_addr_gray[0];
end
end
// Calculate FIFO occupancy
assign fifo_status_full = ll_rx_addr_bin - read_addr_reg + 1;
// Truncate to give 4 bit signal
assign fifo_status_out = fifo_status_full[11:8];
//---------------------------------------------------------------------------
// Hold this signal until the good/bad indicator that signals the
// end of the frame arrives.
//---------------------------------------------------------------------------
always @(posedge rx_clk)
begin
if (rx_reset == 1'b1)
overflow_int_held <= 1'b0;
else if (rx_enable == 1'b1)
begin
if (full_pulse == 1'b1)
overflow_int_held <= 1'b1;
else if (rx_good_frame_reg == 1'b1 || rx_bad_frame_reg == 1'b1)
overflow_int_held <= 1'b0;
end
end
// Assign overflow output signal
assign overflow = overflow_int_held;
//---------------------------------------------------------------------------
// Register the rx and read addresses on their respective clocks. These
// are then input to the overflow processes above.
// **If the FIFO is expanded to use more BRAM, increase rx_addr_reg and
// read_addr_reg size as required **
//---------------------------------------------------------------------------
always @(posedge rx_clk)
begin
if (rx_reset == 1'b1)
rx_addr_reg <= 12'h000;
else if (rx_enable == 1'b1)
rx_addr_reg <= rx_addr;
end
always @(posedge read_clock_in)
begin
if (ll_reset == 1'b1)
read_addr_reg <= 12'h001;
else if (read_addr_enable_int == 1'b1)
read_addr_reg <= read_addr_int;
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -