Skip to content

Instantly share code, notes, and snippets.

@upa
Created May 26, 2016 10:14
Show Gist options
  • Select an option

  • Save upa/576b373fdcbb47765ce39244a6aa722b to your computer and use it in GitHub Desktop.

Select an option

Save upa/576b373fdcbb47765ce39244a6aa722b to your computer and use it in GitHub Desktop.
// fthash.v
// embedded sum of src ip and first half of dst ip to src MAC 8 bit
module one_port #(
// Master AXI Stream Data width
parameter C_M_AXIS_DATA_WIDTH=256,
parameter C_M_AXIS_TUSER_WIDTH=128,
parameter C_S_AXIS_DATA_WIDTH=256,
parameter C_S_AXIS_TUSER_WIDTH=128,
parameter SRC_PORT_POS=16,
parameter DST_PORT_POS=24
) (
// Global ports
input axis_aclk,
input axis_resetn,
// Master Stream Ports (Output)
output reg [C_M_AXIS_DATA_WIDTH - 1:0] m_axis_tdata,
output reg [(C_M_AXIS_DATA_WIDTH / 8) - 1:0] m_axis_tkeep,
output reg [C_M_AXIS_TUSER_WIDTH - 1:0] m_axis_tuser,
output m_axis_tvalid,
output reg m_axis_tlast,
input m_axis_tready,
// Slave Stream Port (Input)
input [C_S_AXIS_DATA_WIDTH - 1:0] s_axis_tdata,
input [(C_S_AXIS_DATA_WIDTH / 8) - 1:0] s_axis_tkeep,
input [C_S_AXIS_TUSER_WIDTH - 1:0] s_axis_tuser,
input s_axis_tvalid,
input s_axis_tlast,
output s_axis_tready
);
wire [C_M_AXIS_TUSER_WIDTH-1:0] tuser_fifo;
wire [C_M_AXIS_DATA_WIDTH-1:0] tdata_fifo;
wire [(C_M_AXIS_DATA_WIDTH / 8) - 1:0] tkeep_fifo;
wire [1:0] tlast_fifo;
reg [C_M_AXIS_TUSER_WIDTH-1:0] tuser_buf;
reg [C_M_AXIS_DATA_WIDTH-1:0] tdata_buf;
reg [(C_M_AXIS_DATA_WIDTH / 8) - 1:0] tkeep_buf;
reg [1:0] tlast_buf;
wire nearly_full_recvfifo;
wire empty_recvfifo;
wire rd_en_recvfifo;
fallthrough_small_fifo #(
.WIDTH(C_S_AXIS_DATA_WIDTH + C_S_AXIS_DATA_WIDTH/8 + C_S_AXIS_TUSER_WIDTH + 1),
.MAX_DEPTH_BITS (4)
) recv_fifo (
.din ({s_axis_tlast, s_axis_tuser, s_axis_tkeep, s_axis_tdata}),
.dout ({tlast_fifo, tuser_fifo, tkeep_fifio, tdata_fifo}),
.wr_en (s_axis_tvalid && ~nearly_full_recvfifo),
.rd_en (rd_en_recvfifo),
.nearly_full (nearly_full_recvfifo),
.prog_full (),
.empty (empty_recvfifo),
.reset (~axis_resetn),
.clk (axis_aclk)
);
// logic
reg [2:0] state;
reg [2:0] state_next;
localparam FIRST_CLOCK = 2'd1;
localparam SECOND_CLOCK = 2'd2;
localparam IN_PACKET = 2'd3;
assign s_axis_tready = !nearly_full_recvfifo;
assign rd_en_recvfifo = !empty_recvfifo && (state == FIRST_CLOCK || m_axis_tready);
assign m_axis_tvalid = !empty_recvfifo && (state == SECOND_CLOCK || state == IN_PACKET);
localparam SRCIP_POS = 208;
localparam DSTIP_POS = 240;
localparam DSTIP_POS_SECOND = 0;
localparam SRCPORT_POS = 16;
localparam DSTPORT_POS = 32;
localparam SRCMAC_POS = 48;
localparam ETHTYPE_POS = 96;
localparam ETHTYPE_IP = 16'h0008;
localparam IPPROTO_POS = 184;
localparam IPPROTO_UDP = 8'h11;
localparam IPPROTO_TCP = 8'h06;
assign trig_fthash = (tdata_buf[ETHTYPE_POS+15:ETHTYPE_POS] == ETHTYPE_IP) &&
(tdata_buf[IPPROTO_POS+7:IPPROTO_POS] == IPPROTO_UDP ||
tdata_buf[IPPROTO_POS+7:IPPROTO_POS] == IPPROTO_TCP);
// trig_fthash means IPv4 TCP or UDP packet
always @ (*) begin
state_next <= state;
case (state)
FIRST_CLOCK: begin
if (rd_en_recvfifo) begin
tuser_buf <= tuser_fifo;
tdata_buf <= tdata_fifo;
tkeep_buf <= tkeep_fifo;
tlast_buf <= tlast_fifo;
state_next <= SECOND_CLOCK;
end
end
SECOND_CLOCK: begin
if (m_axis_tvalid) begin
m_axis_tuser <= tuser_buf;
m_axis_tdata <= tdata_buf;
m_axis_tkeep <= tkeep_buf;
m_axis_tlast <= tlast_buf;
tuser_buf <= tuser_fifo;
tdata_buf <= tdata_fifo;
tkeep_buf <= tkeep_fifo;
tlast_buf <= tlast_fifo;
if (trig_fthash) begin
m_axis_tdata[SRCMAC_POS+07:SRCMAC_POS+00] <= 8'h52;
m_axis_tdata[SRCMAC_POS+15:SRCMAC_POS+08] <= 8'h54;
m_axis_tdata[SRCMAC_POS+23:SRCMAC_POS+16] <= 8'h5e;
m_axis_tdata[SRCMAC_POS+31:SRCMAC_POS+24] <= 8'hBE;
m_axis_tdata[SRCMAC_POS+39:SRCMAC_POS+32] <= 8'hEF;
m_axis_tdata[SRCMAC_POS+47:SRCMAC_POS+40] <=
tdata_buf[SRCIP_POS+07:SRCIP_POS+00] ^
tdata_buf[SRCIP_POS+23:SRCIP_POS+16] ^
tdata_buf[SRCIP_POS+31:SRCIP_POS+24] ^
tdata_buf[DSTIP_POS+07:DSTIP_POS+00] ^
tdata_buf[DSTIP_POS+15:DSTIP_POS+08] ^
tdata_fifo[DSTIP_POS_SECOND+07:DSTIP_POS_SECOND+00] ^
tdata_fifo[DSTIP_POS_SECOND+15:DSTIP_POS_SECOND+08] ^
tdata_fifo[SRCPORT_POS+07:SRCPORT_POS+00] ^
tdata_fifo[SRCPORT_POS+15:SRCPORT_POS+08] ^
tdata_fifo[DSTPORT_POS+07:DSTPORT_POS+00] ^
tdata_fifo[DSTPORT_POS+15:DSTPORT_POS+08];
end
end
if (m_axis_tready) begin
state_next <= IN_PACKET;
end
end
IN_PACKET: begin
m_axis_tuser <= tuser_buf;
m_axis_tdata <= tdata_buf;
m_axis_tkeep <= tkeep_buf;
m_axis_tlast <= tlast_buf;
tuser_buf <= tuser_fifo;
tdata_buf <= tdata_fifo;
tkeep_buf <= tkeep_fifo;
tlast_buf <= tlast_fifo;
if(m_axis_tlast & m_axis_tvalid & m_axis_tready) begin
state_next <= FIRST_CLOCK;
end
end
endcase
end
always @(posedge axis_aclk) begin
if(~axis_resetn) begin
state <= FIRST_CLOCK;
end else begin
state <= state_next;
end
end
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment