Skip to content

Instantly share code, notes, and snippets.

@upa
Last active September 4, 2015 22:36
Show Gist options
  • Save upa/14eef138b5a1ed31a62f to your computer and use it in GitHub Desktop.
Save upa/14eef138b5a1ed31a62f to your computer and use it in GitHub Desktop.
padding 20byte to to of ether frame, netfpga-1g
// padding 20byte to head of the ether frame.
`timescale 1ns/1ps
module padding_packet
#(parameter DATA_WIDTH = 64,
parameter CTRL_WIDTH = DATA_WIDTH/8,
parameter UDP_REG_SRC_WIDTH = 2,
parameter INPUT_ARBITER_STAGE_NUM = 2,
parameter IO_QUEUE_STAGE_NUM = `IO_QUEUE_STAGE_NUM,
parameter NUM_OUTPUT_QUEUES = 8,
parameter NUM_IQ_BITS = 3,
parameter STAGE_NUM = 4,
parameter CPU_QUEUE_NUM = 0)
(// data path interface
output [DATA_WIDTH-1:0] out_data,
output [CTRL_WIDTH-1:0] out_ctrl,
output out_wr,
input out_rdy,
input [DATA_WIDTH-1:0] in_data,
input [CTRL_WIDTH-1:0] in_ctrl,
input in_wr,
output in_rdy,
// misc
input clk,
input reset);
// state parameter
localparam IN_HDR = 1;
localparam IN_OTHRHDR = 2;
localparam IN_PADDING1 = 3; // 8byte
localparam IN_PADDING2 = 4; // 16byte
localparam IN_PADDING3 = 5; // 20 byte, 4 byte tmp
localparam IN_PACKET = 6; //
localparam IN_AMARI = 7;
// wires/regs
wire [CTRL_WIDTH-1:0] in_ctrl_mod;
wire [DATA_WIDTH-1:0] in_data_mod;
reg [CTRL_WIDTH-1:0] out_ctrl_int;
reg [DATA_WIDTH-1:0] out_data_int;
reg [DATA_WIDTH-1:0] tmp_data, tmp_data_nxt;
reg [DATA_WIDTH-1:0] amari_data;
reg [CTRL_WIDTH-1:0] amari_ctrl;
reg [3:0] state, state_nxt;
reg [15:0] new_byte_len;
reg [15:0] new_word_len;
reg out_wr_int;
reg in_fifo_rd_en;
wire im_fifo_nearly_full;
wire in_fifo_empty;
`CEILDIV_FUNC
function integer log2;
input integer number;
begin
log2=0;
while(2**log2<number) begin
log2=log2+1;
end
end
endfunction // log2
// input fifo module
fallthrough_small_fifo
# (.WIDTH (CTRL_WIDTH + DATA_WIDTH), .MAX_DEPTH_BITS (4))
padding_input_fifo
(
.din ({in_ctrl, in_data}), // data in
.wr_en (in_wr),
.rd_en (in_fifo_rd_en),
.dout ({in_ctrl_mod, in_data_mod}),
.full (),
.prog_full (),
.nearly_full (in_fifo_nearly_full),
.empty (in_fifo_empty),
.reset (reset),
.clk (clk)
);
// logic
assign in_rdy = !in_fifo_nearly_full;
assign out_wr = out_wr_int;
assign out_data = out_data_int;
assign out_ctrl = out_ctrl_int;
always @(*) begin
state_nxt = state;
tmp_data_nxt = tmp_data;
out_wr_int = 1'b0;
in_fifo_rd_en = 1'b0;
out_ctrl_int = in_ctrl_mod;
case (state)
IN_HDR : begin
if (!in_fifo_empty && out_rdy) begin
out_wr_int = 1'b1;
in_fifo_rd_en = 1'b1;
if (in_ctrl_mod == IO_QUEUE_STAGE_NUM) begin
new_byte_len = in_data_mod[`IOQ_BYTE_LEN_POS+15:`IOQ_BYTE_LEN_POS] + 20;
new_word_len = ceildiv (new_byte_len, 8);
out_data_int[`IOQ_BYTE_LEN_POS+15:`IOQ_BYTE_LEN_POS] = new_byte_len;
out_data_int[`IOQ_WORD_LEN_POS+15:`IOQ_WORD_LEN_POS] = new_word_len;
state_nxt = IN_OTHRHDR;
end
end
end
IN_OTHRHDR : begin
if (!in_fifo_empty && out_rdy) begin
out_wr_int = 1'b1;
in_fifo_rd_en = 1'b1;
if (in_ctrl_mod != 0) begin
out_data_int = in_data_mod; // other header.
end else begin
// payloda data. stop new data from fifo, and start padding.
out_wr_int = 1'b0;
in_fifo_rd_en = 1'b0;
state_nxt = IN_PADDING1;
end
end
end
IN_PADDING1 : begin
if (out_rdy) begin
out_wr_int = 1'b1;
out_ctrl_int = 8'd0;
out_data_int = 64'd0;
state_nxt = IN_PADDING2;
end
end
IN_PADDING2 : begin
if (out_rdy) begin
out_wr_int = 1'b1;
out_ctrl_int = 8'd0;
out_data_int = 64'd0;
state_nxt = IN_PADDING3;
end
end
IN_PADDING3 : begin
if (!in_fifo_empty && out_rdy) begin
out_wr_int = 1'b1;
in_fifo_rd_en = 1'b1;
out_ctrl_int = 8'd0;
out_data_int = { 32'b0, in_data_mod[63:32] };
tmp_data_nxt = in_data_mod;
state_nxt = IN_PACKET;
end
end
IN_PACKET : begin
if (!in_fifo_empty && out_rdy) begin
out_wr_int = 1'b1;
in_fifo_rd_en = 1'b1;
case (in_ctrl_mod)
'h00 : begin
// a word in the packet.
out_data_int = { tmp_data[31:0], in_data_mod[63:32] };
tmp_data_nxt = in_data_mod;
state_nxt = IN_PACKET;
end
// the last word of the frame
'h80 : begin
out_data_int = { tmp_data[31:0], in_data_mod[63:56], 24'd0 };
out_ctrl_int = 8'h08; // 4 + 1 = 5 byte
state_nxt = IN_HDR;
end
'h40 : begin
out_data_int = { tmp_data[31:0], in_data_mod[63:48], 16'd0 };
out_ctrl_int = 8'h04; // 4 + 2 = 6 byte
state_nxt = IN_HDR;
end
'h20 : begin
out_data_int = { tmp_data[31:0], in_data_mod[63:40], 8'd0 };
out_ctrl_int = 8'h02; // 4 + 3 = 7 byte
state_nxt = IN_HDR;
end
'h10 : begin
out_data_int = { tmp_data[31:0], in_data_mod[63:32] };
out_ctrl_int = 8'h01; // 4 + 4 = 8 byte
state_nxt = IN_HDR;
end
// Amaru case
'h08 : begin
out_data_int = { tmp_data[31:0], in_data_mod[63:32] };
out_ctrl_int = 8'h00;
amari_ctrl = 'h80; // amari 1 byte;
amari_data = { in_data_mod[31:24], 56'd0 };
state_nxt = IN_AMARI;
end
'h04 : begin
out_data_int = { tmp_data[31:0], in_data_mod[63:32] };
out_ctrl_int = 8'h00;
amari_ctrl = 'h40; // amari 2 byte;
amari_data = { in_data_mod[31:16], 48'd0 };
state_nxt = IN_AMARI;
end
'h02 : begin
out_data_int = { tmp_data[31:0], in_data_mod[63:32] };
out_ctrl_int = 8'h00;
amari_ctrl = 'h20; // amari 3 byte;
amari_data = { in_data_mod[31:8], 40'd0 };
state_nxt = IN_AMARI;
end
'h01 : begin
out_data_int = { tmp_data[31:0], in_data_mod[63:32] };
out_ctrl_int = 8'h00;
amari_ctrl = 'h10; // amari 4 byte;
amari_data = { in_data_mod[31:0], 40'd0 };
state_nxt = IN_AMARI;
end
endcase
end
end
IN_AMARI: begin
if (out_rdy) begin
out_wr_int = 1'b1;
out_data_int = amari_data;
out_ctrl_int = amari_ctrl;
state_nxt = IN_HDR;
end
end
endcase
end
always @(posedge clk) begin
if (reset) begin
state <= IN_HDR;
tmp_data <= 0;
end
else begin
state <= state_nxt;
tmp_data <= tmp_data_nxt;
end
end
/* registers unused */
/*
always @(posedge clk) begin
reg_req_out <= reg_req_in;
reg_ack_out <= reg_ack_in;
reg_rd_wr_L_out <= reg_rd_wr_L_in;
reg_addr_out <= reg_addr_in;
reg_data_out <= reg_data_in;
reg_src_out <= reg_src_in;
end */
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment