diff options
Diffstat (limited to 'fpga/usrp3/lib/packet_proc/arm_deframer.v')
-rw-r--r-- | fpga/usrp3/lib/packet_proc/arm_deframer.v | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/packet_proc/arm_deframer.v b/fpga/usrp3/lib/packet_proc/arm_deframer.v new file mode 100644 index 000000000..c4f77edf7 --- /dev/null +++ b/fpga/usrp3/lib/packet_proc/arm_deframer.v @@ -0,0 +1,119 @@ +///////////////////////////////////////////////////////////////////// +// +// Copyright 2017 Ettus Research, A National Instruments Company +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// +// Module: arm_deframer +// Description: +// Adds 6 bytes of Zeros at the beginning of every packet. It aligns the +// 64-bit words of the ethernet packet to be used later for classifying the +// packets. The module is based on xge64_to_axi64 and has lesser +// functionality. +// Note that the block only works for padding 6 bytes. +// +///////////////////////////////////////////////////////////////////// + +module arm_deframer ( + // Clocks and Reset + input wire clk, + input wire reset, + input wire clear, + // Slave AXI Interface + input wire [63:0] s_axis_tdata, + input wire [3:0] s_axis_tuser, //used as tkeep here + input wire s_axis_tlast, + input wire s_axis_tvalid, + output reg s_axis_tready, + // Master AXI Interface + output reg [63:0] m_axis_tdata, + output reg [3:0] m_axis_tuser, //used as tkeep here + output reg m_axis_tlast, + output reg m_axis_tvalid, + input wire m_axis_tready +); + // State Machine States + localparam START = 2'b00; + localparam BODY = 2'b01; + localparam EXTRA = 2'b10; + localparam PAD_BYTES = 3'b110; //6 bytes + wire new_line; + wire valid_beat; + reg [1:0] state = 2'b00, next_state=2'b00; + reg [47:0] holding_reg; + reg [2:0] holding_user; + // New line will be created by padding 6 bytes if the valid bytes on the + // last line are greater than 2 bytes(3 to 7 bytes) or all 8 bytes are valid. + assign new_line = (s_axis_tuser[2:0] > 3'b010) || (s_axis_tuser[2:0] == 3'b000); + assign valid_beat = s_axis_tvalid & m_axis_tready; + always @(posedge clk) begin + if (reset | clear) begin + state <= START; + end else begin + state <=next_state; + end + end + // holding last 48 bits from input tdata on every valid_beat. + always @(posedge clk)begin + if (s_axis_tvalid & s_axis_tready) begin + // Register the last 6 bytes of data for one cycle + holding_reg <= s_axis_tdata[63:16]; + // Register the tuser in case there is a new line + // tuser should be valid for one extra cycle in that case + holding_user <= s_axis_tuser[2:0]; + end + end + // Outputs + always @(*) begin + m_axis_tdata = 64'b0; + m_axis_tvalid = 1'b0; + m_axis_tlast = 1'b0; + m_axis_tuser = 4'b0; + s_axis_tready = 1'b1; + case (state) + START : begin + // Pad with 6 bytes of Zeros at the beginning of the packet + // Shift the first 2 bytes to the end + m_axis_tdata = {s_axis_tdata[15:0], 48'b0}; + m_axis_tvalid = s_axis_tvalid; + m_axis_tlast = s_axis_tlast; + m_axis_tuser = 4'b0; + s_axis_tready = m_axis_tready; + if(valid_beat) next_state = BODY; + else next_state = START; + end + BODY : begin + // Shift the remaining packet by 6 bytes. + // Here we're using register version of data and tvalid. + m_axis_tdata = {s_axis_tdata[15:0], holding_reg}; + m_axis_tvalid = s_axis_tvalid; + m_axis_tlast = new_line? 1'b0: s_axis_tvalid & s_axis_tlast; + // Modify the tuser according to the new packet i.e. add 6 to it. + m_axis_tuser = (new_line & s_axis_tlast) ? 4'b0: {1'b0, s_axis_tuser[2:0] + PAD_BYTES}; + s_axis_tready = m_axis_tready; + if (valid_beat & s_axis_tlast) next_state = new_line ? EXTRA : START; + else next_state = BODY; + end + EXTRA : begin + m_axis_tdata = {16'b0, holding_reg}; + m_axis_tvalid = 1'b1; + m_axis_tlast = 1'b1; + // Modify the tuser according to the new shifted packet i.e. add 6 to it. + m_axis_tuser = {1'b0, holding_user + PAD_BYTES}; + // We need to hold off any comming upstream data i.e not ready until + // downstream done consuming this data + s_axis_tready = 1'b0; + if (m_axis_tready) next_state = START; + else next_state = EXTRA; + end + default : begin + m_axis_tdata = 64'b0; + m_axis_tvalid = 1'b0; + m_axis_tlast = 1'b0; + m_axis_tuser = 4'b0; + s_axis_tready = 1'b1; + next_state = START; + end + endcase + end +endmodule // arm_deframer |