RX Client FIFO
The rx_client_fifo is built around a dual port
block RAM
Providing a total memory capacity of 4096
bytes of frame data.
The receive FIFO writes in data received
through the Ethernet MAC.
Frame is presented on the LocalLink
interface for reading by you,
TX Client FIFO
The tx_client_fifo is built around a dual port
block RAM
Providing a total memory capacity of 4096
bytes of frame data.
When frame is written into FIFO , the FIFO presents data to the
MAC transmitter .
Address Swap Module
The module takes frame data
from Ethernet MAC LocalLink client
interface .
The module interchanges the final point and source
addresses of each frame to ensure that the
outgoing output address fixes the
source address of the link partner
module ASM(
input clk,
input rst,
input [7:0] rx_ll_data_in,
input rx_ll_sof_in_n,
input rx_ll_eof_in_n,
output reg [7:0] rx_ll_data_out,
output rx_ll_sof_out_n,
output rx_ll_eof_out_n
);
reg [7:0] data_sr_content [5:0];
reg [6:0] sof_sr_content;
reg [6:0] eof_sr_content;
reg en_data_sr;
wire [7:0] mux_out;
reg sel_delay_path;
parameter wait_sf = 3'b000;
parameter bypass_sa1 = 3'b001;
parameter bypass_sa2 = 3'b010;
parameter bypass_sa3 = 3'b011;
parameter bypass_sa4 = 3'b100;
parameter bypass_sa5 = 3'b101;
parameter bypass_sa6 = 3'b110;
parameter pass_rof = 3'b111;
reg [2:0] state, next_state;
always @(posedge clk)
begin
if(rst)
state <= 0;
else
state <= next_state;
end
always @(*)
begin
case(state)
wait_sf:
if(sof_sr_content[4])
next_state = bypass_sa1;
else
next_state = wait_sf;
bypass_sa1:
next_state = bypass_sa2;
bypass_sa2:
next_state = bypass_sa3;
bypass_sa3:
next_state = bypass_sa4;
bypass_sa4:
next_state = bypass_sa5;
bypass_sa5:
next_state = bypass_sa6;
bypass_sa6:
next_state = pass_rof;
pass_rof:
if(eof_sr_content[4])
next_state = wait_sf;
else
next_state = pass_rof;
default:
next_state = wait_sf;
endcase
end
always @(*)
begin
case(state)
wait_sf:
begin
sel_delay_path = 0;
en_data_sr = 1;
end
bypass_sa1:
begin
sel_delay_path = 1;
en_data_sr = 0;
end
bypass_sa2:
begin
sel_delay_path = 1;
en_data_sr = 0;
end
bypass_sa3:
begin
sel_delay_path = 1;
en_data_sr = 0;
end
bypass_sa4:
begin
sel_delay_path = 1;
en_data_sr = 0;
end
bypass_sa5:
begin
sel_delay_path = 1;
en_data_sr = 0;
end
bypass_sa6:
begin
sel_delay_path = 1;
en_data_sr = 0;
end
pass_rof:
begin
sel_delay_path = 0;
en_data_sr = 1;
end
default:
begin
sel_delay_path = 0;
en_data_sr = 1;
end
endcase
end
assign mux_out = sel_delay_path ? rx_ll_data_in:data_sr_content[5];
always @(posedge clk)
begin
if(rst)
rx_ll_data_out <= 0;
else
rx_ll_data_out <= mux_out;
end
always @(posedge clk)
begin
if(rst)
begin
data_sr_content[0] <= 0;
data_sr_content[1] <= 0;
data_sr_content[2] <= 0;
data_sr_content[3] <= 0;
data_sr_content[4] <= 0;
data_sr_content[5] <= 0;
end
else if (en_data_sr)
begin
data_sr_content[0] <= rx_ll_data_in;
data_sr_content[1] <= data_sr_content[0];
data_sr_content[2] <= data_sr_content[1];
data_sr_content[3] <= data_sr_content[2];
data_sr_content[4] <= data_sr_content[3];
data_sr_content[5] <= data_sr_content[4];
end
else
begin
data_sr_content[0] <= data_sr_content[0];
data_sr_content[1] <= data_sr_content[1];
data_sr_content[2] <= data_sr_content[2];
data_sr_content[3] <= data_sr_content[3];
data_sr_content[4] <= data_sr_content[4];
data_sr_content[5] <= data_sr_content[5];
end
end
always @(posedge clk)
begin
if(rst)
begin
sof_sr_content[0] <= 0;
sof_sr_content[1] <= 0;
sof_sr_content[2] <= 0;
sof_sr_content[3] <= 0;
sof_sr_content[4] <= 0;
sof_sr_content[5] <= 0;
sof_sr_content[6] <= 0;
end
else
begin
sof_sr_content[0] <= ~rx_ll_sof_in_n;
sof_sr_content[1] <= sof_sr_content[0];
sof_sr_content[2] <= sof_sr_content[1];
sof_sr_content[3] <= sof_sr_content[2];
sof_sr_content[4] <= sof_sr_content[3];
sof_sr_content[5] <= sof_sr_content[4];
sof_sr_content[6] <= sof_sr_content[5];
end
end
always @(posedge clk)
begin
if(rst)
begin
eof_sr_content[0] <= 0;
eof_sr_content[1] <= 0;
eof_sr_content[2] <= 0;
eof_sr_content[3] <= 0;
eof_sr_content[4] <= 0;
eof_sr_content[5] <= 0;
eof_sr_content[6] <= 0;
end
else
begin
eof_sr_content[0] <= ~rx_ll_eof_in_n;
eof_sr_content[1] <= eof_sr_content[0];
eof_sr_content[2] <= eof_sr_content[1];
eof_sr_content[3] <= eof_sr_content[2];
eof_sr_content[4] <= eof_sr_content[3];
eof_sr_content[5] <= eof_sr_content[4];
eof_sr_content[6] <= eof_sr_content[5];
end
end
assign rx_ll_sof_out_n = ~sof_sr_content[6];
assign rx_ll_eof_out_n = ~eof_sr_content[6];
endmodule
Stimulus:
module stimulus;
reg clk, rst, sof_in, eof_in;
reg [7:0] data_in;
wire [7:0] data_out;
wire sof_out,eof_out;
ASM ASM_inst(
.clk (clk ),
.rst (rst ),
.rx_ll_data_in (data_in),
.rx_ll_sof_in_n (sof_in ),
.rx_ll_eof_in_n (eof_in ),
.rx_ll_data_out (data_out),
.rx_ll_sof_out_n (sof_out ),
.rx_ll_eof_out_n (eof_out )
);
integer i;
always
#5 clk = ~clk;
initial
begin
rst = 1;
clk = 0;
sof_in = 1;
eof_in = 1;
repeat(10)
@(posedge clk);
rst = 0;
@(posedge clk);
sof_in = 0;
data_in = 1;
@(posedge clk);
sof_in = 1;
for(i=2;i<=20;i=i+1)
begin
data_in = i;
@(posedge clk);
end
eof_in = 0;
data_in = 21;
@(posedge clk);
eof_in = 1;
end
endmodule