Created
May 30, 2016 17:00
-
-
Save upa/9e5d580aec67d3258c308535b1868b9a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 reg m_axis_tvalid, | |
output reg m_axis_tlast, | |
input wire m_axis_tready, | |
// Slave Stream Port (Input) | |
input wire [C_S_AXIS_DATA_WIDTH - 1:0] s_axis_tdata, | |
input wire [(C_S_AXIS_DATA_WIDTH / 8) - 1:0] s_axis_tkeep, | |
input wire [C_S_AXIS_TUSER_WIDTH - 1:0] s_axis_tuser, | |
input wire s_axis_tvalid, | |
input wire s_axis_tlast, | |
output wire 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 tlast_fifo; | |
reg [C_M_AXIS_TUSER_WIDTH-1:0] tuser_buf0, tuser_buf1; | |
reg [C_M_AXIS_DATA_WIDTH-1:0] tdata_buf0, tdata_buf1; | |
reg [(C_M_AXIS_DATA_WIDTH / 8) - 1:0] tkeep_buf0, tkeep_buf1; | |
reg tlast_buf0, tlast_buf1; | |
reg [C_M_AXIS_TUSER_WIDTH-1:0] tuser_fifo_next, tuser_buf0_next, tuser_buf1_next; | |
reg [C_M_AXIS_DATA_WIDTH-1:0] tdata_fifo_next, tdata_buf0_next, tdata_buf1_next; | |
reg [(C_M_AXIS_DATA_WIDTH / 8) - 1:0] tkeep_fifo_next, tkeep_buf0_next, tkeep_buf1_next; | |
reg tlast_fifo_next, tlast_buf0_next, tlast_buf1_next; | |
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_fifo, 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) | |
); | |
/* | |
* FSM state machine | |
*/ | |
localparam DATA0 = 2'd0, | |
DATA1 = 2'd1, | |
DATA2 = 2'd2, | |
IN_PACKET = 2'd3; | |
reg [1:0] state; | |
reg [1:0] state_next; | |
assign s_axis_tready = !nearly_full_recvfifo; | |
assign rd_en_recvfifo = !empty_recvfifo && m_axis_tready; | |
// (state == DATA0 || state == DATA1 || | |
// state == DATA2 || state == IN_PACKET); | |
// In DATA0 | |
localparam SRCMAC_POS = 48; | |
localparam ETHTYPE_POS = 96; | |
localparam IPPROTO_POS = 184; | |
// In DATA1 | |
localparam SRCIP_POS = 208; | |
localparam DSTIP_POS = 240; | |
localparam DSTIP_POS_SECOND = 0; | |
// In DATA2 | |
localparam SRCPORT_POS = 16; | |
localparam DSTPORT_POS = 32; | |
// Triger Parameter | |
localparam ETHTYPE_IP = 16'h0008; | |
localparam IPPROTO_UDP = 8'h11; | |
localparam IPPROTO_TCP = 8'h06; | |
assign trig_fthash = | |
(tdata_fifo_next[ETHTYPE_POS+15:ETHTYPE_POS] == ETHTYPE_IP) && | |
(tdata_fifo_next[IPPROTO_POS+7:IPPROTO_POS] == IPPROTO_UDP || | |
tdata_fifo_next[IPPROTO_POS+7:IPPROTO_POS] == IPPROTO_TCP); | |
wire [15:0] debug_eth = tdata_buf0[ETHTYPE_POS+15:ETHTYPE_POS]; | |
wire [7:0] debug_ip = tdata_buf0[IPPROTO_POS+7:IPPROTO_POS]; | |
// trig_fthash means IPv4 TCP or UDP packet | |
always @ (*) begin | |
state_next = state; | |
case (state) | |
DATA0: begin | |
m_axis_tvalid = 0; | |
if (rd_en_recvfifo) begin | |
tuser_fifo_next = tuser_fifo; | |
tdata_fifo_next = tdata_fifo; | |
tkeep_fifo_next = tkeep_fifo; | |
tlast_fifo_next = tlast_fifo; | |
tuser_buf0_next = tuser_buf0; | |
tdata_buf0_next = tdata_buf0; | |
tkeep_buf0_next = tkeep_buf0; | |
tlast_buf0_next = tlast_buf0; | |
tuser_buf1_next = tuser_buf1; | |
tdata_buf1_next = tdata_buf1; | |
tkeep_buf1_next = tkeep_buf1; | |
tlast_buf1_next = tlast_buf1; | |
state_next = DATA1; | |
end | |
end | |
DATA1: begin | |
m_axis_tvalid = 0; | |
if (rd_en_recvfifo) begin | |
tuser_fifo_next = tuser_fifo; | |
tdata_fifo_next = tdata_fifo; | |
tkeep_fifo_next = tkeep_fifo; | |
tlast_fifo_next = tlast_fifo; | |
tuser_buf0_next = tuser_buf0; | |
tdata_buf0_next = tdata_buf0; | |
tkeep_buf0_next = tkeep_buf0; | |
tlast_buf0_next = tlast_buf0; | |
tuser_buf1_next = tuser_buf1; | |
tdata_buf1_next = tdata_buf1; | |
tkeep_buf1_next = tkeep_buf1; | |
tlast_buf1_next = tlast_buf1; | |
state_next = DATA2; | |
end | |
end | |
DATA2: begin | |
m_axis_tvalid = 0; | |
if (rd_en_recvfifo) begin | |
tuser_fifo_next = tuser_fifo; | |
tdata_fifo_next = tdata_fifo; | |
tkeep_fifo_next = tkeep_fifo; | |
tlast_fifo_next = tlast_fifo; | |
tuser_buf0_next = tuser_buf0; | |
tdata_buf0_next = tdata_buf0; | |
tkeep_buf0_next = tkeep_buf0; | |
tlast_buf0_next = tlast_buf0; | |
tuser_buf1_next = tuser_buf1; | |
tdata_buf1_next = tdata_buf1; | |
tkeep_buf1_next = tkeep_buf1; | |
tlast_buf1_next = tlast_buf1; | |
//if (m_axis_tready) | |
// m_axis_tvalid = 1; | |
if (trig_fthash) begin | |
tdata_buf1_next[SRCMAC_POS+07:SRCMAC_POS+00] = 8'h52; | |
tdata_buf1_next[SRCMAC_POS+15:SRCMAC_POS+08] = 8'h54; | |
tdata_buf1_next[SRCMAC_POS+23:SRCMAC_POS+16] = 8'h5e; | |
tdata_buf1_next[SRCMAC_POS+31:SRCMAC_POS+24] = 8'hBE; | |
tdata_buf1_next[SRCMAC_POS+39:SRCMAC_POS+32] = 8'hEF; | |
tdata_buf1_next[SRCMAC_POS+47:SRCMAC_POS+40] = | |
tdata_buf0_next[SRCIP_POS+07:SRCIP_POS+00] ^ | |
tdata_buf0_next[SRCIP_POS+23:SRCIP_POS+16] ^ | |
tdata_buf0_next[SRCIP_POS+31:SRCIP_POS+24] ^ | |
tdata_buf0_next[DSTIP_POS+07:DSTIP_POS+00] ^ | |
tdata_buf0_next[DSTIP_POS+15:DSTIP_POS+08] ^ | |
tdata_fifo_next[DSTIP_POS_SECOND+07:DSTIP_POS_SECOND+00] ^ | |
tdata_fifo_next[DSTIP_POS_SECOND+15:DSTIP_POS_SECOND+08] ^ | |
tdata_fifo_next[SRCPORT_POS+07:SRCPORT_POS+00] ^ | |
tdata_fifo_next[SRCPORT_POS+15:SRCPORT_POS+08] ^ | |
tdata_fifo_next[DSTPORT_POS+07:DSTPORT_POS+00] ^ | |
tdata_fifo_next[DSTPORT_POS+15:DSTPORT_POS+08]; | |
end | |
end | |
if (m_axis_tready) begin | |
state_next = IN_PACKET; | |
end | |
end | |
IN_PACKET: begin | |
m_axis_tvalid = 0; | |
if (m_axis_tready) begin | |
m_axis_tvalid = 1; | |
tuser_fifo_next = tuser_fifo; | |
tdata_fifo_next = tdata_fifo; | |
tkeep_fifo_next = tkeep_fifo; | |
tlast_fifo_next = tlast_fifo; | |
tuser_buf0_next = tuser_buf0; | |
tdata_buf0_next = tdata_buf0; | |
tkeep_buf0_next = tkeep_buf0; | |
tlast_buf0_next = tlast_buf0; | |
tuser_buf1_next = tuser_buf1; | |
tdata_buf1_next = tdata_buf1; | |
tkeep_buf1_next = tkeep_buf1; | |
tlast_buf1_next = tlast_buf1; | |
end | |
if(m_axis_tlast & m_axis_tvalid & m_axis_tready) begin | |
state_next = DATA0; | |
end | |
end | |
endcase | |
end | |
always @(posedge axis_aclk) begin | |
if(~axis_resetn) begin | |
state <= DATA0; | |
tuser_buf0 <= 0; | |
tdata_buf0 <= 0; | |
tkeep_buf0 <= 0; | |
tlast_buf0 <= 0; | |
tuser_buf1 <= 0; | |
tdata_buf1 <= 0; | |
tkeep_buf1 <= 0; | |
tlast_buf1 <= 0; | |
m_axis_tuser <= 0; | |
m_axis_tdata <= 0; | |
m_axis_tkeep <= 0; | |
m_axis_tlast <= 0; | |
end else begin | |
state <= state_next; | |
if (rd_en_recvfifo) begin | |
tuser_buf0 <= tuser_fifo_next; | |
tdata_buf0 <= tdata_fifo_next; | |
tkeep_buf0 <= tkeep_fifo_next; | |
tlast_buf0 <= tlast_fifo_next; | |
tuser_buf1 <= tuser_buf0_next; | |
tdata_buf1 <= tdata_buf0_next; | |
tkeep_buf1 <= tkeep_buf0_next; | |
tlast_buf1 <= tlast_buf0_next; | |
m_axis_tuser <= tuser_buf1_next; | |
m_axis_tdata <= tdata_buf1_next; | |
m_axis_tkeep <= tkeep_buf1_next; | |
m_axis_tlast <= tlast_buf1_next; | |
end | |
end | |
end | |
endmodule |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
`timescale 1ns/1ps | |
module tb(); | |
localparam FREQ = 20; | |
reg clk; | |
initial clk = 1'b0; | |
always #(FREQ/2) clk <= ~clk; | |
reg rstn; | |
initial rstn = 1'b0; | |
reg [255:0] tdata; | |
reg tlast; | |
wire tready; | |
reg tvalid = 0; | |
reg m_tready; | |
reg [3:0] random = 0; | |
integer i; | |
//wire [255:0] data_0 = 256'h0101A8C066554433221101000506070801020608665544332211FFFFFFFFFFFF; | |
//wire [255:0] data_1 = 256'h000000000000000000000000000000000000000000006401A8C0000000000000; | |
// | |
// DSTMAC SRCMAC TYPE IP Parameters SRCIP DSTIP | |
// 256'h_001111000001_001111000002_0080_45000054b4be00004001b4fb_ac100001_ac10 | |
// | |
// // DSTIP ICMP ECHO REQUEST Header and Body | |
// 256'h_0002_0800f9a72a77000c5746e7b4000aa9cc08090a0b0c0d0e0f1011121314151 | |
// | |
// // ICMP Echo--- | |
// 256'h_61718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233343536 | |
// 256'h_37000000000000000000000000000000000000000000000000000000000000000 | |
wire [255:0] data_upa_0 = 256'h10ac010010acfbb411400000beb4540000450008020000111100010000111100; | |
//001111000001001111000002000845000054b4be00004001b4fbac100001ac10; | |
wire [255:0] data_upa_1 = 256'h1514131211100f0e0d0c0b0a0908cca90a00b4e746570c00772aa7f900080200; | |
//00020800f9a72a77000c5746e7b4000aa9cc08090a0b0c0d0e0f101112131415; | |
wire [255:0] data_upa_2 = 256'h3534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a19181716; | |
//161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435; | |
wire [255:0] data_upa_3 = 256'h0000000000000000000000000000000000000000000000000000000000003736; | |
//3637000000000000000000000000000000000000000000000000000000000000; | |
localparam IDLE = 0; | |
localparam DATA_0 = 1; | |
localparam DATA_1 = 2; | |
localparam DATA_2 = 3; | |
localparam DATA_3 = 4; | |
localparam DEAD = 5; | |
localparam STOP_0 = 6; | |
localparam STOP_1 = 7; | |
localparam STOP_2 = 8; | |
localparam STOP_3 = 9; | |
localparam STOP_4 = 11; | |
localparam STOP_5 = 12; | |
localparam STOP_6 = 13; | |
localparam STOP_7 = 14; | |
reg [6:0] state, state_next; | |
reg [7:0] counter, counter_next; | |
always @(*) begin | |
state_next = state; | |
tdata = 256'b0; | |
tlast = 1'b0; | |
counter_next = counter; | |
case(state) | |
IDLE : begin | |
tdata = 0; | |
tvalid = 0; | |
state_next = DATA_0; | |
m_tready = 0; | |
end | |
DATA_0: begin | |
tdata = data_upa_0; | |
tvalid = 1; | |
m_tready = 1; | |
if(tready) begin | |
state_next = DATA_1; | |
end | |
end | |
DATA_1: begin | |
tdata = data_upa_1; | |
m_tready = 1; | |
if(tready) begin | |
state_next = DATA_2; | |
end | |
end | |
DATA_2: begin | |
tdata = data_upa_2; | |
if(tready) begin | |
state_next = DATA_3; | |
end | |
end | |
DATA_3: begin | |
tdata = data_upa_3; | |
tlast = 1; | |
if(tready) begin | |
state_next = STOP_1; | |
end | |
end | |
STOP_1: begin | |
tdata = 0; | |
m_tready = 1; | |
state_next = STOP_2; | |
end | |
STOP_2: begin | |
tdata = 0; | |
m_tready = 0; | |
state_next = STOP_3; | |
end | |
STOP_3: begin | |
tdata = 0; | |
m_tready = 1; | |
state_next = STOP_4; | |
end | |
STOP_4: begin | |
tdata = 0; | |
m_tready = 1; | |
state_next = STOP_5; | |
end | |
STOP_5: begin | |
tdata = 0; | |
m_tready = 1; | |
state_next = STOP_6; | |
end | |
STOP_6: begin | |
tdata = 0; | |
m_tready = 1; | |
state_next = DEAD; | |
end | |
STOP_3: begin | |
tdata = 0; | |
m_tready = 1; | |
state_next = DEAD; | |
end | |
DEAD: begin | |
tlast = 1'b0; | |
tvalid = 0; | |
end | |
endcase | |
end | |
always @(posedge clk) begin | |
if(~rstn) begin | |
state <= IDLE; | |
counter <= 8'b0; | |
end else begin | |
state <= state_next; | |
counter <= counter_next; | |
end | |
end | |
one_port inst_u ( | |
// Global ports | |
.axis_aclk(clk), | |
.axis_resetn(rstn), | |
// Master Stream Ports (Output) | |
.m_axis_tdata(), | |
.m_axis_tkeep(), | |
.m_axis_tuser(), | |
.m_axis_tvalid(), | |
.m_axis_tlast(), | |
.m_axis_tready(m_tready), | |
// Slave Stream Port (Input) | |
.s_axis_tdata(tdata), | |
.s_axis_tkeep(32'hFFFF_FFFF), | |
.s_axis_tuser(128'h0004AAAA), | |
.s_axis_tvalid(tvalid), | |
.s_axis_tlast(tlast), | |
.s_axis_tready(tready) | |
); | |
task waitclk; | |
begin | |
#FREQ; | |
end | |
endtask | |
initial begin | |
$dumpfile("dump.vcd"); | |
$dumpvars(0, tb); | |
rstn = 1'b0; | |
waitclk; | |
waitclk; | |
waitclk; | |
waitclk; | |
rstn = 1'b1; | |
#3000; | |
$finish(); | |
end | |
endmodule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment