URL
https://opencores.org/ocsvn/loadbalancer/loadbalancer/trunk
Subversion Repositories loadbalancer
[/] [loadbalancer/] [trunk/] [output_port_lookup.v.bak] - Rev 2
Compare with Previous | Blame | View Log
///////////////////////////////////////////////////////////////////////////////// vim:set shiftwidth=3 softtabstop=3 expandtab:// $Id: output_port_lookup.v 2201 2007-08-21 06:52:51Z jnaous $//// Module: switch_output_port.v// Project: NF2.1// Description: reads incoming packets parses them and decides on the output port// and adds it as a header. The design of this module assumes that only one eop// will be in the pipeline of this module at any given time.// i.e. we assume pkt length incl pkt and module headers >= 8*DATA_WIDTH bits// for a 64 bit datapath, this is 64 bytes./////////////////////////////////////////////////////////////////////////////////`timescale 1ns/1psmodule output_port_lookup#(parameter DATA_WIDTH = 64,parameter CTRL_WIDTH=DATA_WIDTH/8,parameter UDP_REG_SRC_WIDTH = 2,parameter INPUT_ARBITER_STAGE_NUM = 2,parameter NUM_OUTPUT_QUEUES = 8,parameter STAGE_NUM = 4,parameter NUM_IQ_BITS = 3)(// --- data path interfaceoutput reg [DATA_WIDTH-1:0] out_data,output reg [CTRL_WIDTH-1:0] out_ctrl,output reg 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,input en,// --- Miscinput clk,input reset);function integer log2;input integer number;beginlog2=0;while(2**log2<number) beginlog2=log2+1;endendendfunction // log2//--------------------- Internal Parameter-------------------------parameter LUT_DEPTH_BITS = 4;parameter DEFAULT_MISS_OUTPUT_PORTS = 8'b01010101; // exclude the CPU queuesparameter NUM_STATES = 4;parameter WAIT_TILL_DONE_DECODE = 1;parameter WRITE_HDR = 2;parameter SKIP_HDRS = 4;parameter WAIT_EOP = 8;//---------------------- Wires and regs----------------------------wire lookup_ack;wire [47:0] dst_mac;wire [47:0] src_mac;wire [15:0] ethertype;wire [NUM_IQ_BITS-1:0] src_port;wire eth_done;wire [NUM_OUTPUT_QUEUES-1:0] dst_ports;wire [NUM_OUTPUT_QUEUES-1:0] dst_ports_latched;wire [LUT_DEPTH_BITS-1:0] rd_addr; // address in table to readwire rd_req; // request a readwire [NUM_OUTPUT_QUEUES-1:0] rd_oq; // data read from the LUT at rd_addrwire rd_wr_protect; // wr_protect bit readwire [47:0] rd_mac; // data to match in the CAMwire rd_ack; // pulses high when data is rdywire [LUT_DEPTH_BITS-1:0] wr_addr;wire wr_req;wire [NUM_OUTPUT_QUEUES-1:0] wr_oq;wire wr_protect; // wr_protect bit to writewire [47:0] wr_mac; // data to match in the CAMwire wr_ack; // pulses high when wr is donewire lut_hit; // pulses high on a hitwire lut_miss; // pulses high on a missreg in_fifo_rd_en;wire [CTRL_WIDTH-1:0] in_fifo_ctrl_dout;wire [DATA_WIDTH-1:0] in_fifo_data_dout;wire in_fifo_nearly_full;wire in_fifo_empty;reg dst_port_rd;wire dst_port_fifo_nearly_full;wire dst_port_fifo_empty;reg [NUM_STATES-1:0] state, state_next;//------------------------- Modules-------------------------------ethernet_parser#(.DATA_WIDTH (DATA_WIDTH),.CTRL_WIDTH (CTRL_WIDTH),.NUM_IQ_BITS(NUM_IQ_BITS),.INPUT_ARBITER_STAGE_NUM(INPUT_ARBITER_STAGE_NUM))eth_parser(.in_data(in_data),.in_ctrl(in_ctrl),.in_wr(in_wr),.dst_mac (dst_mac),.src_mac(src_mac),.ethertype (ethertype),.eth_done (eth_done),.src_port(src_port),.reset(reset),.clk(clk));/* The size of this fifo has to be large enough to fit the previous modules' headers* and the ethernet header */small_fifo #(.WIDTH(DATA_WIDTH+CTRL_WIDTH), .MAX_DEPTH_BITS(4), .NEARLY_FULL(15))input_fifo(.din ({in_ctrl,in_data}), // Data in.wr_en (in_wr), // Write enable.rd_en (in_fifo_rd_en), // Read the next word.dout ({in_fifo_ctrl_dout, in_fifo_data_dout}),.full (),.nearly_full (in_fifo_nearly_full),.empty (in_fifo_empty),.reset (reset),.clk (clk));small_fifo #(.WIDTH(NUM_OUTPUT_QUEUES), .MAX_DEPTH_BITS(2), .NEARLY_FULL(3))dst_port_fifo(.din (dst_ports), // Data in.wr_en (lut_hit|lut_miss), // Write enable.rd_en (dst_port_rd), // Read the next word.dout (dst_ports_latched),.full (),.nearly_full (dst_port_fifo_nearly_full),.empty (dst_port_fifo_empty),.reset (reset),.clk (clk));//----------------------- Logic -----------------------------assign in_rdy = !in_fifo_nearly_full && !dst_port_fifo_nearly_full;/********************************************************************** Wait until the ethernet header has been decoded and the output* port is found, then write the module header and move the packet* to the output**********************************************************************/always @(*) beginout_ctrl = in_fifo_ctrl_dout;out_data = in_fifo_data_dout;state_next = state;out_wr = 0;in_fifo_rd_en = 0;dst_port_rd = 0;case(state)WAIT_TILL_DONE_DECODE: beginif(!dst_port_fifo_empty) begindst_port_rd = 1;state_next = WRITE_HDR;in_fifo_rd_en = 1;endend/* write Destionation output ports */WRITE_HDR: beginif(out_rdy) beginif(in_fifo_ctrl_dout==2'hFF) beginout_data[31:16] = dst_ports_latched;endout_wr = 1;in_fifo_rd_en = 1;state_next = SKIP_HDRS;endend/* Skip the rest of the headers */SKIP_HDRS: beginif(in_fifo_ctrl_dout==0) beginstate_next = WAIT_EOP;endif(!in_fifo_empty & out_rdy) beginin_fifo_rd_en = 1;out_wr = 1;endend/* write all data */WAIT_EOP: beginif(in_fifo_ctrl_dout!=0)beginif(out_rdy) beginstate_next = WAIT_TILL_DONE_DECODE;out_wr = 1;endendelse if(!in_fifo_empty & out_rdy) beginin_fifo_rd_en = 1;out_wr = 1;endend // case: WAIT_EOPendcase // case(state)end // always @ (*)always @(posedge clk) beginif(reset) beginstate <= WAIT_TILL_DONE_DECODE;endelse beginstate <= state_next;endendendmodule // switch_output_port
