diff options
Diffstat (limited to 'fpga/usrp3/lib')
| -rw-r--r-- | fpga/usrp3/lib/io_port2/Makefile.srcs | 1 | ||||
| -rw-r--r-- | fpga/usrp3/lib/io_port2/pcie_basic_regs.v | 9 | ||||
| -rw-r--r-- | fpga/usrp3/lib/io_port2/pcie_dma_ctrl.v | 17 | ||||
| -rw-r--r-- | fpga/usrp3/lib/io_port2/pcie_lossy_samp_gate.v | 26 | ||||
| -rw-r--r-- | fpga/usrp3/lib/packet_proc/eth_dispatch.v | 937 | ||||
| -rw-r--r-- | fpga/usrp3/lib/vita/new_tx_control.v | 40 | 
6 files changed, 531 insertions, 499 deletions
diff --git a/fpga/usrp3/lib/io_port2/Makefile.srcs b/fpga/usrp3/lib/io_port2/Makefile.srcs index 507b8895a..4ee23a7b4 100644 --- a/fpga/usrp3/lib/io_port2/Makefile.srcs +++ b/fpga/usrp3/lib/io_port2/Makefile.srcs @@ -16,4 +16,5 @@ IOPORT2_SRCS = $(abspath $(addprefix $(BASE_DIR)/../lib/io_port2/, \  ./pcie_basic_regs.v \  ./pcie_dma_ctrl.v \  ./data_swapper_64.v \ +./pcie_lossy_samp_gate.v \  )) diff --git a/fpga/usrp3/lib/io_port2/pcie_basic_regs.v b/fpga/usrp3/lib/io_port2/pcie_basic_regs.v index e3790e81c..e360b6812 100644 --- a/fpga/usrp3/lib/io_port2/pcie_basic_regs.v +++ b/fpga/usrp3/lib/io_port2/pcie_basic_regs.v @@ -3,7 +3,10 @@  // -module pcie_basic_regs ( +module pcie_basic_regs #( +    parameter SIGNATURE = 32'h0, +    parameter CLK_FREQ  = 32'h0 +) (      input           clk,      input           reset, @@ -16,8 +19,8 @@ module pcie_basic_regs (      input [31:0]    misc_status  ); -    localparam PCIE_FPGA_SIG_VAL                = 32'h58333030; //X300 (ASCII) -    localparam PCIE_FPGA_COUNTER_FREQ           = 32'h0A6E49C0; //175MHz +    localparam PCIE_FPGA_SIG_VAL                = SIGNATURE; +    localparam PCIE_FPGA_COUNTER_FREQ           = CLK_FREQ;      localparam PCIE_REG_ADDR_MASK               = 20'h001FF; diff --git a/fpga/usrp3/lib/io_port2/pcie_dma_ctrl.v b/fpga/usrp3/lib/io_port2/pcie_dma_ctrl.v index 6809939af..9e0f05040 100644 --- a/fpga/usrp3/lib/io_port2/pcie_dma_ctrl.v +++ b/fpga/usrp3/lib/io_port2/pcie_dma_ctrl.v @@ -35,12 +35,14 @@ module pcie_dma_ctrl #(      output          rego_tvalid,      input           rego_tready, +    output reg [NUM_STREAMS-1:0]            set_enabled,      output reg [NUM_STREAMS-1:0]            set_clear,      output [(NUM_STREAMS*FRAME_SIZE_W)-1:0] set_frame_size,      output [(NUM_STREAMS*3)-1:0]            swap_lanes,      input  [NUM_STREAMS-1:0]                packet_stb,      input  [NUM_STREAMS-1:0]                sample_stb, +    input  [NUM_STREAMS-1:0]                stream_busy,      input  [NUM_STREAMS-1:0]                stream_err,      input  [ROUTER_SID_W-1:0]               rtr_sid, @@ -48,7 +50,7 @@ module pcie_dma_ctrl #(  );      localparam DMA_REG_GRP_W        = 4; -    localparam DMA_CTRL_STATUS_REG  = 4'h0; //[RW] R: Stream Error, W: Reset stream +    localparam DMA_CTRL_STATUS_REG  = 4'h0; //[RW] R: Stream Status, W: Stream Control      localparam DMA_FSIZE_REG        = 4'h4; //[RW] R: Frame Size, W: Frame Size      localparam DMA_SAMP_CNT_REG     = 4'h8; //[RW] R: Sample Count, W: Reset Count to 0      localparam DMA_PKT_CNT_REG      = 4'hC; //[RW] R: Packet Count, W: Reset Count to 0 @@ -92,14 +94,15 @@ module pcie_dma_ctrl #(                  if (reset) begin                      frame_size_mem[i] <= DEFAULT_FSIZE;                      set_clear[i] <= 0; +                    set_enabled[i] <= 0;                      sw_buf_width_mem[i] <= 1;                  end else if (regi_tready & regi_tvalid & regi_wr) begin                      if (regi_addr == `GET_REG_OFFSET(DMA_CTRL_STATUS_REG, i)) begin -                        set_clear[i] <= regi_payload[0];                        //DMA_CTRL_STATUS_REG[0] == Clear DMA queues +                        set_clear[i]        <= regi_payload[0];                 //DMA_CTRL_STATUS_REG[0] == Clear DMA queues +                        set_enabled[i]      <= regi_payload[1];                 //DMA_CTRL_STATUS_REG[1] == Enable DMA channel                          sw_buf_width_mem[i] <= regi_payload[4];                 //DMA_CTRL_STATUS_REG[5:4] == SW Buffer Size (See note above)                      end else if (regi_addr == `GET_REG_OFFSET(DMA_FSIZE_REG, i)) begin                          frame_size_mem[i] <= regi_payload[FRAME_SIZE_W-1:0];    //DMA_FSIZE_REG[14:0] == DMA Frame size -                        set_clear[i] <= 1;                      end                  end else begin                      set_clear[i] <= 0;                                          //set_clear should be "self-clearing" @@ -123,7 +126,7 @@ module pcie_dma_ctrl #(                      samp_count_mem[i] <= samp_count_mem[i] + 1;                  end              end -        end             +        end      endgenerate      //Readback @@ -131,14 +134,14 @@ module pcie_dma_ctrl #(          (regi_addr[DMA_REG_GRP_W-1:0] == DMA_PKT_CNT_REG)     ?      pkt_count_mem[`EXTRACT_CHAN_NUM(regi_addr)]  : (          (regi_addr[DMA_REG_GRP_W-1:0] == DMA_SAMP_CNT_REG)    ?     samp_count_mem[`EXTRACT_CHAN_NUM(regi_addr)]  : (          (regi_addr[DMA_REG_GRP_W-1:0] == DMA_FSIZE_REG)       ?     frame_size_mem[`EXTRACT_CHAN_NUM(regi_addr)]  : ( -        (regi_addr[DMA_REG_GRP_W-1:0] == DMA_CTRL_STATUS_REG) ? {31'h0, stream_err[`EXTRACT_CHAN_NUM(regi_addr)]} : ( +        (regi_addr[DMA_REG_GRP_W-1:0] == DMA_CTRL_STATUS_REG) ? {30'h0, stream_busy[`EXTRACT_CHAN_NUM(regi_addr)], stream_err[`EXTRACT_CHAN_NUM(regi_addr)]} : (          32'hFFFFFFFF))));      assign rego_tvalid = regi_tvalid && regi_rd;      assign regi_tready = rego_tready || (regi_tvalid && regi_wr);      //Optional router -    if (ENABLE_ROUTER == 1) begin +    generate if (ENABLE_ROUTER == 1) begin          pcie_pkt_route_specifier #(              .BASE_ADDR((1<<ROUTER_SID_W) + REG_BASE_ADDR), .ADDR_MASK(20'hFFFFF^((1<<ROUTER_SID_W)-1)),              .SID_WIDTH(ROUTER_SID_W), .DST_WIDTH(ROUTER_DST_W) @@ -147,7 +150,7 @@ module pcie_dma_ctrl #(              .regi_tdata(regi_tdata), .regi_tvalid(regi_tvalid), .regi_tready(),              .local_sid(rtr_sid), .fifo_dst(rtr_dst)          ); -    end +    end endgenerate  endmodule diff --git a/fpga/usrp3/lib/io_port2/pcie_lossy_samp_gate.v b/fpga/usrp3/lib/io_port2/pcie_lossy_samp_gate.v new file mode 100644 index 000000000..6f6b6377a --- /dev/null +++ b/fpga/usrp3/lib/io_port2/pcie_lossy_samp_gate.v @@ -0,0 +1,26 @@ +// +// Copyright 2013 Ettus Research LLC +// + + +module pcie_lossy_samp_gate +( +   input [63:0]   i_tdata, +   input          i_tvalid, +   output         i_tready, +    +   output [63:0]  o_tdata, +   output         o_tvalid, +   input          o_tready, +    +   input          drop, +   output         dropping +); + +   assign o_tdata    = i_tdata; +   assign o_tvalid   = i_tvalid & ~drop; +   assign i_tready   = o_tready | drop; +    +   assign dropping   = drop & i_tvalid; +    +endmodule // pcie_lossy_samp_gate diff --git a/fpga/usrp3/lib/packet_proc/eth_dispatch.v b/fpga/usrp3/lib/packet_proc/eth_dispatch.v index 7068d5a77..07f40d50e 100644 --- a/fpga/usrp3/lib/packet_proc/eth_dispatch.v +++ b/fpga/usrp3/lib/packet_proc/eth_dispatch.v @@ -11,7 +11,7 @@  //  the vita port.  //  //  If at the end of the headers we determine the packet should go to zpu, then we send an -//  error indication on the out port, the rest of the packet to zpu and nothing on vita.   +//  error indication on the out port, the rest of the packet to zpu and nothing on vita.  //  If it should go to out, we send the error indication to zpu, the rest of the packet to out,  //  and nothing on vita.  // @@ -40,148 +40,148 @@ module eth_dispatch    #(parameter BASE=0)     (      // Clocking and reset interface -    input clk,  -    input reset,  -    input clear,  +    input clk, +    input reset, +    input clear,      // Setting register interface -    input set_stb,  -    input [15:0] set_addr,  +    input set_stb, +    input [15:0] set_addr,      input [31:0] set_data,      // Input 68bit AXI-Stream interface (from MAC) -    input [63:0] in_tdata,  -    input [3:0] in_tuser,  -    input in_tlast,  -    input in_tvalid,  +    input [63:0] in_tdata, +    input [3:0] in_tuser, +    input in_tlast, +    input in_tvalid,      output in_tready,      // Output AXI-STream interface to VITA Radio Core      output [63:0] vita_tdata, -    output [3:0] vita_tuser,  -    output vita_tlast,  -    output vita_tvalid,  +    output [3:0] vita_tuser, +    output vita_tlast, +    output vita_tvalid,      input vita_tready,      // Output AXI-Stream interface to ZPU -    output [63:0] zpu_tdata,  -    output [3:0] zpu_tuser,  -    output zpu_tlast,  -    output zpu_tvalid,  +    output [63:0] zpu_tdata, +    output [3:0] zpu_tuser, +    output zpu_tlast, +    output zpu_tvalid,      input zpu_tready,      // Output AXI-Stream interface to cross-over MAC -    output [63:0] xo_tdata,  -    output [3:0] xo_tuser,  -    output xo_tlast,  -    output xo_tvalid,  +    output [63:0] xo_tdata, +    output [3:0] xo_tuser, +    output xo_tlast, +    output xo_tvalid,      input xo_tready,      // Debug      output [2:0] debug_flags,      output [31:0] debug      ); -   // -   // State machine declarations -   // -   reg [2:0] 	  state; -    -   localparam WAIT_PACKET = 0; -   localparam READ_HEADER = 1; -   localparam FORWARD_ZPU = 2; -   localparam FORWARD_ZPU_AND_XO = 3; -   localparam FORWARD_XO = 4; -   localparam FORWARD_RADIO_CORE = 5; -   localparam DROP_PACKET = 6; -   localparam CLASSIFY_PACKET = 7; -    -       -   // -   // Small RAM stores packet header during parsing. -   // -   // IJB consider changing HEADER_RAM_SIZE to 7 -   localparam HEADER_RAM_SIZE = 9; -   (*ram_style="distributed"*) -   reg [68:0] 	  header_ram [HEADER_RAM_SIZE-1:0]; -   reg [3:0] 	  header_ram_addr; -   reg 		  drop_this_packet; - -   wire 	  header_done = (header_ram_addr == HEADER_RAM_SIZE-1); -   reg 		  fwd_input; - -   // -   reg [63:0] 	  in_tdata_reg; -    -   // -   wire 	  out_tvalid; -   wire 	  out_tready; -   wire 	  out_tlast; -   wire [3:0] 	  out_tuser; -   wire [63:0] 	  out_tdata; -    -   // -   // Output AXI-Stream interface to VITA Radio Core -   wire [63:0] 	  vita_pre_tdata; -   wire [3:0] 	  vita_pre_tuser;  -   wire 	  vita_pre_tlast;  -   wire 	  vita_pre_tvalid;  -   wire 	  vita_pre_tready; -   // Output AXI-Stream interface to ZPU -   wire [63:0] 	  zpu_pre_tdata;  -   wire [3:0] 	  zpu_pre_tuser;  -   wire 	  zpu_pre_tlast;  -   wire 	  zpu_pre_tvalid;  -   wire 	  zpu_pre_tready; -   // Output AXI-Stream interface to cross-over MAC -   wire [63:0] 	  xo_pre_tdata;  -   wire [3:0] 	  xo_pre_tuser;  -   wire 	  xo_pre_tlast;  -   wire 	  xo_pre_tvalid;  -   wire 	  xo_pre_tready; - -   // -   // Packet Parse Flags -   // -   reg 		  is_eth_dst_addr; -   reg 		  is_eth_broadcast; -   reg 		  is_eth_type_ipv4; -   reg 		  is_ipv4_dst_addr; -   reg 		  is_ipv4_proto_udp; -   reg 		  is_ipv4_proto_icmp; -   reg [1:0] 	  is_udp_dst_ports; -   reg		  is_icmp_no_fwd; -   reg 		  is_chdr; -    -   // -   // Settings regs -   // -    -   wire [47:0] 	  my_mac; -    -   setting_reg #(.my_addr(BASE), .awidth(16), .width(32)) sr_my_mac_lsb -     (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), -      .in(set_data),.out(my_mac[31:0]),.changed()); - -   setting_reg #(.my_addr(BASE+1), .awidth(16), .width(16)) sr_my_mac_msb -     (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), -      .in(set_data),.out(my_mac[47:32]),.changed()); - -   wire [31:0] 	  my_ip; -    -   setting_reg #(.my_addr(BASE+2), .awidth(16), .width(32)) sr_my_ip -     (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), -      .in(set_data),.out(my_ip[31:0]),.changed()); -    -   wire [15:0] 	  my_port0, my_port1; -    -   setting_reg #(.my_addr(BASE+3), .awidth(16), .width(32)) sr_udp_port -     (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), -      .in(set_data),.out({my_port1[15:0],my_port0[15:0]}),.changed()); - -   wire forward_ndest, forward_bcast; -   setting_reg #(.my_addr(BASE+4), .awidth(16), .width(2)) sr_forward_ctrl -     (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), -      .in(set_data),.out({forward_ndest, forward_bcast}),.changed()); - -   wire [7:0] my_icmp_type, my_icmp_code; -   setting_reg #(.my_addr(BASE+5), .awidth(16), .width(16)) sr_icmp_ctrl -     (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), -      .in(set_data),.out({my_icmp_type, my_icmp_code}),.changed()); +    // +    // State machine declarations +    // +    reg [2:0] 	  state; + +    localparam WAIT_PACKET = 0; +    localparam READ_HEADER = 1; +    localparam FORWARD_ZPU = 2; +    localparam FORWARD_ZPU_AND_XO = 3; +    localparam FORWARD_XO = 4; +    localparam FORWARD_RADIO_CORE = 5; +    localparam DROP_PACKET = 6; +    localparam CLASSIFY_PACKET = 7; + + +    // +    // Small RAM stores packet header during parsing. +    // +    // IJB consider changing HEADER_RAM_SIZE to 7 +    localparam HEADER_RAM_SIZE = 9; +    (*ram_style="distributed"*) +    reg [68:0] 	  header_ram [HEADER_RAM_SIZE-1:0]; +    reg [3:0] 	  header_ram_addr; +    reg 		  drop_this_packet; + +    wire 	  header_done = (header_ram_addr == HEADER_RAM_SIZE-1); +    reg 		  fwd_input; + +    // +    reg [63:0] 	  in_tdata_reg; + +    // +    wire 	  out_tvalid; +    wire 	  out_tready; +    wire 	  out_tlast; +    wire [3:0] 	  out_tuser; +    wire [63:0] 	  out_tdata; + +    // +    // Output AXI-Stream interface to VITA Radio Core +    wire [63:0] 	  vita_pre_tdata; +    wire [3:0] 	  vita_pre_tuser; +    wire 	  vita_pre_tlast; +    wire 	  vita_pre_tvalid; +    wire 	  vita_pre_tready; +    // Output AXI-Stream interface to ZPU +    wire [63:0] 	  zpu_pre_tdata; +    wire [3:0] 	  zpu_pre_tuser; +    wire 	  zpu_pre_tlast; +    wire 	  zpu_pre_tvalid; +    wire 	  zpu_pre_tready; +    // Output AXI-Stream interface to cross-over MAC +    wire [63:0] 	  xo_pre_tdata; +    wire [3:0] 	  xo_pre_tuser; +    wire 	  xo_pre_tlast; +    wire 	  xo_pre_tvalid; +    wire 	  xo_pre_tready; + +    // +    // Packet Parse Flags +    // +    reg 		  is_eth_dst_addr; +    reg 		  is_eth_broadcast; +    reg 		  is_eth_type_ipv4; +    reg 		  is_ipv4_dst_addr; +    reg 		  is_ipv4_proto_udp; +    reg 		  is_ipv4_proto_icmp; +    reg [1:0] 	  is_udp_dst_ports; +    reg		  is_icmp_no_fwd; +    reg 		  is_chdr; + +    // +    // Settings regs +    // + +    wire [47:0] 	  my_mac; + +    setting_reg #(.my_addr(BASE), .awidth(16), .width(32)) sr_my_mac_lsb +        (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), +        .in(set_data),.out(my_mac[31:0]),.changed()); + +    setting_reg #(.my_addr(BASE+1), .awidth(16), .width(16)) sr_my_mac_msb +        (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), +        .in(set_data),.out(my_mac[47:32]),.changed()); + +    wire [31:0] 	  my_ip; + +    setting_reg #(.my_addr(BASE+2), .awidth(16), .width(32)) sr_my_ip +        (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), +        .in(set_data),.out(my_ip[31:0]),.changed()); + +    wire [15:0] 	  my_port0, my_port1; + +    setting_reg #(.my_addr(BASE+3), .awidth(16), .width(32)) sr_udp_port +        (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), +        .in(set_data),.out({my_port1[15:0],my_port0[15:0]}),.changed()); + +    wire forward_ndest, forward_bcast; +    setting_reg #(.my_addr(BASE+4), .awidth(16), .width(2)) sr_forward_ctrl +        (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), +        .in(set_data),.out({forward_ndest, forward_bcast}),.changed()); + +    wire [7:0] my_icmp_type, my_icmp_code; +    setting_reg #(.my_addr(BASE+5), .awidth(16), .width(16)) sr_icmp_ctrl +        (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), +        .in(set_data),.out({my_icmp_type, my_icmp_code}),.changed());      assign debug =      { @@ -194,347 +194,346 @@ module eth_dispatch      }; -   // -   // Packet Forwarding State machine. -   // -    -   always @(posedge clk)  -     if (reset || clear) begin -        state <= WAIT_PACKET; -        header_ram_addr <= 0; -	drop_this_packet <= 0;	  -	fwd_input <= 0; -     end else begin -	// Defaults. -	drop_this_packet <= 0; -	 -	case(state) -	  // -	  // Wait for start of a packet -	  // IJB: Add protection for a premature EOF here -	  // -	  WAIT_PACKET: begin  -	     if (in_tvalid && in_tready) begin -                header_ram[header_ram_addr] <= {in_tlast,in_tuser,in_tdata}; -                header_ram_addr <= header_ram_addr + 1; -		state <= READ_HEADER; -	     end -	     fwd_input <= 0; -          end -	  // -	  // Continue to read full packet header into RAM. -	  // -	  READ_HEADER: begin -	     if (in_tvalid && in_tready) begin -		header_ram[header_ram_addr] <= {in_tlast,in_tuser,in_tdata}; -		// Have we reached end of fields we parse in header or got a short packet? -		if (header_done || in_tlast) begin -		   // Make decision about where this packet is forwarded to. -		   state <= CLASSIFY_PACKET; -		end // if (header_done || in_tlast) -		else begin -		   header_ram_addr <= header_ram_addr + 1; -		   state <= READ_HEADER; -		end // else: !if(header_done || in_tlast) -	     end // if (in_tvalid && in_tready) -	  end // case: READ_HEADER - -	  // -	  // Classify Packet  -	  // -	  CLASSIFY_PACKET: begin -	     // Make decision about where this packet is forwarded to. -	     if (is_eth_type_ipv4 && is_ipv4_proto_icmp && is_icmp_no_fwd) begin -	        header_ram_addr <= 0; -		state <= FORWARD_ZPU; -	     end else if (is_eth_broadcast) begin -		header_ram_addr <= 0; -		state <= forward_bcast? FORWARD_ZPU_AND_XO : FORWARD_ZPU; -	     end else if (!is_eth_dst_addr) begin -		header_ram_addr <= 0; -		state <= forward_ndest? FORWARD_XO : DROP_PACKET; -	     end else if ((is_udp_dst_ports != 0) && is_chdr) begin -		header_ram_addr <= 6;  // Jump to CHDR -		state <= FORWARD_RADIO_CORE; -	     end else if (drop_this_packet) begin -		header_ram_addr <= HEADER_RAM_SIZE-1; -		state  <= DROP_PACKET; -	     end else begin -		header_ram_addr <= 0; -		state <= FORWARD_ZPU; -	     end -	  end // case: CLASSIFY_PACKET -	  	   -	  // -	  // Forward this packet only to local ZPU -	  // -	  FORWARD_ZPU: begin -	     if (out_tvalid && out_tready) begin -		if (out_tlast) begin -		   state <= WAIT_PACKET; -		end -		if (header_done) fwd_input <= 1; -		header_ram_addr <= out_tlast? 4'b0 : header_ram_addr + 1; -	     end -	  end -	  // -	  // Forward this packet to both local ZPU and XO  -	  // -	  FORWARD_ZPU_AND_XO: begin -	     if (out_tvalid && out_tready) begin -		if (out_tlast) begin -		   state <= WAIT_PACKET; -		end -		if (header_done) fwd_input <= 1; -		header_ram_addr <= out_tlast? 4'b0 : header_ram_addr + 1; -	     end -	  end -	  // -	  // Forward this packet to XO only -	  // -	  FORWARD_XO: begin -	     if (out_tvalid && out_tready) begin -		if (out_tlast) begin -		   state <= WAIT_PACKET; -		end -		if (header_done) fwd_input <= 1; -		header_ram_addr <= out_tlast? 4'b0 : header_ram_addr + 1; -	     end -	  end -	  // -	  // Forward this packet to the Radio Core only -	  // -	  FORWARD_RADIO_CORE: begin -	     if (out_tvalid && out_tready) begin -		if (out_tlast) begin -		   state <= WAIT_PACKET; -		end -		if (header_done) fwd_input <= 1; -		header_ram_addr <= out_tlast? 4'b0 : header_ram_addr + 1; -	     end -	  end -	  // -	  // Drop this packet on the ground -	  // -	  DROP_PACKET: begin -	     if (out_tvalid && out_tready) begin -		if (out_tlast) begin -		   state <= WAIT_PACKET; -		end -		if (header_done) fwd_input <= 1; -		header_ram_addr <= out_tlast? 4'b0 : header_ram_addr + 1; -	     end -	  end -	endcase // case (state) -     end // else: !if(reset || clear) -    -   // -   // Classifier State machine. -   // Deep packet inspection during header ingress. -   // -   always @(posedge clk) -     if (reset || clear) begin -	is_eth_dst_addr <= 1'b0; -	is_eth_broadcast <= 1'b0; -	is_eth_type_ipv4 <= 1'b0; -	is_ipv4_dst_addr <= 1'b0; -	is_ipv4_proto_udp <=  1'b0; -	is_ipv4_proto_icmp <=  1'b0; -	is_udp_dst_ports <= 0; -	is_icmp_no_fwd <= 0; -	is_chdr <= 1'b0; -	 -	//	   space_in_fifo <= 0; -	//	   is_there_fifo_space <= 1; -	//	   packet_length <= 0; -     end else if (in_tvalid && in_tready) begin // if (reset || clear) -	in_tdata_reg <= in_tdata; -	 -	case (header_ram_addr) -	  // Pipelined, so nothing to look at first cycle. -	  // Reset all the flags here. -	  0: begin -	     is_eth_dst_addr <= 1'b0; -	     is_eth_broadcast <= 1'b0; -	     is_eth_type_ipv4 <= 1'b0; -	     is_ipv4_dst_addr <= 1'b0; -	     is_ipv4_proto_udp <=  1'b0; -	     is_ipv4_proto_icmp <=  1'b0; -	     is_udp_dst_ports <= 0; -	     is_icmp_no_fwd <= 0; -	     is_chdr <= 1'b0; -	  end -	  1: begin -	     // Look at upper 16bits of MAC Dst Addr. -	     if (in_tdata_reg[15:0] == 16'hFFFF) -	       is_eth_broadcast <= 1'b1; -	     if (in_tdata_reg[15:0] == my_mac[47:32]) -	       is_eth_dst_addr <= 1'b1; -	  end -	  2: begin	 -	     // Look at lower 32bits of MAC Dst Addr. -	     if (is_eth_broadcast && (in_tdata_reg[63:32] == 32'hFFFFFFFF)) -	       is_eth_broadcast <= 1'b1; -	     else -	       is_eth_broadcast <= 1'b0; -	     if (is_eth_dst_addr && (in_tdata_reg[63:32] == my_mac[31:0])) -		  is_eth_dst_addr <= 1'b1; -		else -		  is_eth_dst_addr <= 1'b0; -	     end // case: 2 -	     3: begin -		// Look at Ethertype -		if (in_tdata_reg[47:32] == 16'h0800) -		  is_eth_type_ipv4 <= 1'b1; -		// Extract Packet Length -		// ADD THIS HERE. -	     end -	     4: begin -		// Look at protocol enapsulated by IPv4 -		if ((in_tdata_reg[23:16] == 8'h11) && is_eth_type_ipv4) -		  is_ipv4_proto_udp <= 1'b1; -		if ((in_tdata_reg[23:16] == 8'h01) && is_eth_type_ipv4) -		  is_ipv4_proto_icmp <= 1'b1; -	     end -	     5: begin -		// Look at IP DST Address. -		if ((in_tdata_reg[31:0] == my_ip[31:0]) && is_eth_type_ipv4) -		  is_ipv4_dst_addr <= 1'b1; -	     end -	     6: begin -		// Look at UDP dest port -		if ((in_tdata_reg[47:32] == my_port0[15:0]) && is_ipv4_proto_udp) -		  is_udp_dst_ports[0] <= 1'b1; -		if ((in_tdata_reg[47:32] == my_port1[15:0]) && is_ipv4_proto_udp) -		  is_udp_dst_ports[1] <= 1'b1; -		// Look at ICMP type and code -		if (in_tdata_reg[63:48] == {my_icmp_type, my_icmp_code} && is_ipv4_proto_icmp) -		  is_icmp_no_fwd <= 1'b1; -	     end -	     7: begin -		// Look for a possible CHDR header string -		// IJB. NOTE this is not a good test for a CHDR packet, we perhaps don;t need this state anyhow. -		if (in_tdata_reg[63:32] != 32'h0) -		  is_chdr <= 1'b1; -	     end -	     8: begin -		// Check VRT Stream ID -		// ADD THIS HERE. -		// IJB. Perhaps delete this state. -	     end -	   endcase // case (header_ram_addr) -	end // if (in_tvalid && in_tready) -    -    -   // -   // Output (Egress) Interface muxing -   // -   assign out_tready =  -		       (state == DROP_PACKET) || -		       ((state == FORWARD_RADIO_CORE) && vita_pre_tready) || -		       ((state == FORWARD_XO) && xo_pre_tready) || -	   	       ((state == FORWARD_ZPU) && zpu_pre_tready) || -		       ((state == FORWARD_ZPU_AND_XO) && zpu_pre_tready && xo_pre_tready); - -   assign out_tvalid = ((state == FORWARD_RADIO_CORE) || -			(state == FORWARD_XO) || -			(state == FORWARD_ZPU) || -			(state == FORWARD_ZPU_AND_XO) || -			(state == DROP_PACKET)) && (!fwd_input || in_tvalid); - -   assign {out_tlast,out_tuser,out_tdata} = fwd_input ?  {in_tlast,in_tuser,in_tdata} : header_ram[header_ram_addr]; -    -   assign in_tready = (state == WAIT_PACKET) ||  -		      (state == READ_HEADER) || -		      (state == DROP_PACKET) || -		      (out_tready && fwd_input); -    - -   // -   // Because we can forward to both the ZPU and XO FIFO's concurrently -   // we have to make sure both can accept data in the same cycle. -   // This makes it possible for either destination to block the other. -   // Make sure (both) destination(s) can accept data before passing it. -   // -   assign xo_pre_tvalid = out_tvalid &&  -			  ((state == FORWARD_XO) ||  -			  ((state == FORWARD_ZPU_AND_XO) && zpu_pre_tready)); -   assign zpu_pre_tvalid = out_tvalid &&  -			   ((state == FORWARD_ZPU) || -			   ((state == FORWARD_ZPU_AND_XO) && xo_pre_tready)); -   assign vita_pre_tvalid = out_tvalid && (state == FORWARD_RADIO_CORE); -    -   assign {zpu_pre_tuser,zpu_pre_tdata} = ((state == FORWARD_ZPU_AND_XO) || (state == FORWARD_ZPU)) ? -					  {out_tuser,out_tdata} : 0; - -   assign {xo_pre_tuser,xo_pre_tdata} = ((state == FORWARD_ZPU_AND_XO) || (state == FORWARD_XO)) ? -					{out_tuser,out_tdata} : 0; - -   assign {vita_pre_tuser,vita_pre_tdata} = (state == FORWARD_RADIO_CORE) ? {out_tuser,out_tdata} : 0; - -   assign zpu_pre_tlast = out_tlast && ((state == FORWARD_ZPU) || (state == FORWARD_ZPU_AND_XO)); -    -   assign xo_pre_tlast =  out_tlast && ((state == FORWARD_XO) || (state == FORWARD_ZPU_AND_XO)); -    -   assign vita_pre_tlast = out_tlast && (state == FORWARD_RADIO_CORE); -    -   // -   // Egress FIFO's (Large) -   // -   axi_fifo #(.WIDTH(69),.SIZE(10))  -   axi_fifo_zpu ( -     .clk(clk), -     .reset(reset), -     .clear(clear), -     .i_tdata({zpu_pre_tlast,zpu_pre_tuser,zpu_pre_tdata}), -     .i_tvalid(zpu_pre_tvalid), -     .i_tready(zpu_pre_tready), -     .o_tdata({zpu_tlast,zpu_tuser,zpu_tdata}), -     .o_tvalid(zpu_tvalid), -     .o_tready(zpu_tready), -     .space(), -     .occupied() -     ); -    -   axi_fifo #(.WIDTH(69),.SIZE(10))  -   axi_fifo_xo ( -     .clk(clk), -     .reset(reset), -     .clear(clear), -     .i_tdata({xo_pre_tlast,xo_pre_tuser,xo_pre_tdata}), -     .i_tvalid(xo_pre_tvalid), -     .i_tready(xo_pre_tready), -     .o_tdata({xo_tlast,xo_tuser,xo_tdata}), -     .o_tvalid(xo_tvalid), -     .o_tready(xo_tready), -     .space(), -     .occupied() -     ); -    -   axi_fifo #(.WIDTH(69),.SIZE(10))  -   axi_fifo_vita (      -     .clk(clk), -     .reset(reset), -     .clear(clear), -     .i_tdata({vita_pre_tlast,vita_pre_tuser,vita_pre_tdata}), -     .i_tvalid(vita_pre_tvalid), -     .i_tready(vita_pre_tready), -     .o_tdata({vita_tlast,vita_tuser,vita_tdata}), -     .o_tvalid(vita_tvalid), -     .o_tready(vita_tready), -     .space(), -     .occupied() -     ); - -   assign debug_flags = {vita_pre_tready,xo_pre_tready,zpu_pre_tready}; -    -  -      +    // +    // Packet Forwarding State machine. +    // + +    always @(posedge clk) +        if (reset || clear) begin +            state <= WAIT_PACKET; +            header_ram_addr <= 0; +            drop_this_packet <= 0; +            fwd_input <= 0; +        end else begin +            // Defaults. +            drop_this_packet <= 0; + +            case(state) +                // +                // Wait for start of a packet +                // IJB: Add protection for a premature EOF here +                // +                WAIT_PACKET: begin +                    if (in_tvalid && in_tready) begin +                        header_ram[header_ram_addr] <= {in_tlast,in_tuser,in_tdata}; +                        header_ram_addr <= header_ram_addr + 1; +                        state <= READ_HEADER; +                    end +                    fwd_input <= 0; +                end +                // +                // Continue to read full packet header into RAM. +                // +                READ_HEADER: begin +                    if (in_tvalid && in_tready) begin +                        header_ram[header_ram_addr] <= {in_tlast,in_tuser,in_tdata}; +                        // Have we reached end of fields we parse in header or got a short packet? +                        if (header_done || in_tlast) begin +                            // Make decision about where this packet is forwarded to. +                            state <= CLASSIFY_PACKET; +                        end // if (header_done || in_tlast) +                        else begin +                            header_ram_addr <= header_ram_addr + 1; +                            state <= READ_HEADER; +                        end // else: !if(header_done || in_tlast) +                    end // if (in_tvalid && in_tready) +                end // case: READ_HEADER + +                // +                // Classify Packet +                // +                CLASSIFY_PACKET: begin +                    // Make decision about where this packet is forwarded to. +                    if (is_eth_type_ipv4 && is_ipv4_proto_icmp && is_icmp_no_fwd) begin +                        header_ram_addr <= 0; +                        state <= FORWARD_ZPU; +                    end else if (is_eth_broadcast) begin +                        header_ram_addr <= 0; +                        state <= forward_bcast? FORWARD_ZPU_AND_XO : FORWARD_ZPU; +                    end else if (!is_eth_dst_addr) begin +                        header_ram_addr <= 0; +                        state <= forward_ndest? FORWARD_XO : DROP_PACKET; +                    end else if ((is_udp_dst_ports != 0) && is_chdr) begin +                        header_ram_addr <= 6;  // Jump to CHDR +                        state <= FORWARD_RADIO_CORE; +                    end else if (drop_this_packet) begin +                        header_ram_addr <= HEADER_RAM_SIZE-1; +                        state  <= DROP_PACKET; +                    end else begin +                        header_ram_addr <= 0; +                        state <= FORWARD_ZPU; +                    end +                end // case: CLASSIFY_PACKET + +                // +                // Forward this packet only to local ZPU +                // +                FORWARD_ZPU: begin +                    if (out_tvalid && out_tready) begin +                        if (out_tlast) begin +                            state <= WAIT_PACKET; +                        end +                        if (header_done) fwd_input <= 1; +                        header_ram_addr <= out_tlast? 4'b0 : header_ram_addr + 1; +                    end +                end +                // +                // Forward this packet to both local ZPU and XO +                // +                FORWARD_ZPU_AND_XO: begin +                    if (out_tvalid && out_tready) begin +                        if (out_tlast) begin +                            state <= WAIT_PACKET; +                        end +                        if (header_done) fwd_input <= 1; +                        header_ram_addr <= out_tlast? 4'b0 : header_ram_addr + 1; +                    end +                end +                // +                // Forward this packet to XO only +                // +                FORWARD_XO: begin +                    if (out_tvalid && out_tready) begin +                        if (out_tlast) begin +                            state <= WAIT_PACKET; +                        end +                        if (header_done) fwd_input <= 1; +                        header_ram_addr <= out_tlast? 4'b0 : header_ram_addr + 1; +                    end +                end +                // +                // Forward this packet to the Radio Core only +                // +                FORWARD_RADIO_CORE: begin +                    if (out_tvalid && out_tready) begin +                        if (out_tlast) begin +                            state <= WAIT_PACKET; +                        end +                        if (header_done) fwd_input <= 1; +                        header_ram_addr <= out_tlast? 4'b0 : header_ram_addr + 1; +                    end +                end +                // +                // Drop this packet on the ground +                // +                DROP_PACKET: begin +                    if (out_tvalid && out_tready) begin +                        if (out_tlast) begin +                            state <= WAIT_PACKET; +                        end +                        if (header_done) fwd_input <= 1; +                        header_ram_addr <= out_tlast? 4'b0 : header_ram_addr + 1; +                    end +                end +            endcase // case (state) +        end // else: !if(reset || clear) + +    // +    // Classifier State machine. +    // Deep packet inspection during header ingress. +    // +    always @(posedge clk) +        if (reset || clear) begin +            is_eth_dst_addr <= 1'b0; +            is_eth_broadcast <= 1'b0; +            is_eth_type_ipv4 <= 1'b0; +            is_ipv4_dst_addr <= 1'b0; +            is_ipv4_proto_udp <=  1'b0; +            is_ipv4_proto_icmp <=  1'b0; +            is_udp_dst_ports <= 0; +            is_icmp_no_fwd <= 0; +            is_chdr <= 1'b0; + +            //space_in_fifo <= 0; +            //is_there_fifo_space <= 1; +            //packet_length <= 0; +        end else if (in_tvalid && in_tready) begin // if (reset || clear) +            in_tdata_reg <= in_tdata; + +            case (header_ram_addr) +                // Pipelined, so nothing to look at first cycle. +                // Reset all the flags here. +                0: begin +                    is_eth_dst_addr <= 1'b0; +                    is_eth_broadcast <= 1'b0; +                    is_eth_type_ipv4 <= 1'b0; +                    is_ipv4_dst_addr <= 1'b0; +                    is_ipv4_proto_udp <=  1'b0; +                    is_ipv4_proto_icmp <=  1'b0; +                    is_udp_dst_ports <= 0; +                    is_icmp_no_fwd <= 0; +                    is_chdr <= 1'b0; +                end +                1: begin +                    // Look at upper 16bits of MAC Dst Addr. +                    if (in_tdata_reg[15:0] == 16'hFFFF) +                        is_eth_broadcast <= 1'b1; +                    if (in_tdata_reg[15:0] == my_mac[47:32]) +                        is_eth_dst_addr <= 1'b1; +                end +                2: begin +                    // Look at lower 32bits of MAC Dst Addr. +                    if (is_eth_broadcast && (in_tdata_reg[63:32] == 32'hFFFFFFFF)) +                        is_eth_broadcast <= 1'b1; +                    else +                        is_eth_broadcast <= 1'b0; +                    if (is_eth_dst_addr && (in_tdata_reg[63:32] == my_mac[31:0])) +                        is_eth_dst_addr <= 1'b1; +                    else +                        is_eth_dst_addr <= 1'b0; +                end // case: 2 +                3: begin +                    // Look at Ethertype +                    if (in_tdata_reg[47:32] == 16'h0800) +                        is_eth_type_ipv4 <= 1'b1; +                    // Extract Packet Length +                    // ADD THIS HERE. +                end +                4: begin +                    // Look at protocol enapsulated by IPv4 +                    if ((in_tdata_reg[23:16] == 8'h11) && is_eth_type_ipv4) +                        is_ipv4_proto_udp <= 1'b1; +                    if ((in_tdata_reg[23:16] == 8'h01) && is_eth_type_ipv4) +                        is_ipv4_proto_icmp <= 1'b1; +                end +                5: begin +                    // Look at IP DST Address. +                    if ((in_tdata_reg[31:0] == my_ip[31:0]) && is_eth_type_ipv4) +                        is_ipv4_dst_addr <= 1'b1; +                end +                6: begin +                    // Look at UDP dest port +                    if ((in_tdata_reg[47:32] == my_port0[15:0]) && is_ipv4_proto_udp) +                        is_udp_dst_ports[0] <= 1'b1; +                    if ((in_tdata_reg[47:32] == my_port1[15:0]) && is_ipv4_proto_udp) +                        is_udp_dst_ports[1] <= 1'b1; +                    // Look at ICMP type and code +                    if (in_tdata_reg[63:48] == {my_icmp_type, my_icmp_code} && is_ipv4_proto_icmp) +                        is_icmp_no_fwd <= 1'b1; +                end +                7: begin +                    // Look for a possible CHDR header string +                    // IJB. NOTE this is not a good test for a CHDR packet, we perhaps don;t need this state anyhow. +                    if (in_tdata_reg[63:32] != 32'h0) +                        is_chdr <= 1'b1; +                end +                8: begin +                    // Check VRT Stream ID +                    // ADD THIS HERE. +                    // IJB. Perhaps delete this state. +                end +            endcase // case (header_ram_addr) +        end // if (in_tvalid && in_tready) + + +    // +    // Output (Egress) Interface muxing +    // +    assign out_tready = +        (state == DROP_PACKET) || +        ((state == FORWARD_RADIO_CORE) && vita_pre_tready) || +        ((state == FORWARD_XO) && xo_pre_tready) || +        ((state == FORWARD_ZPU) && zpu_pre_tready) || +        ((state == FORWARD_ZPU_AND_XO) && zpu_pre_tready && xo_pre_tready); + +    assign out_tvalid = ((state == FORWARD_RADIO_CORE) || +        (state == FORWARD_XO) || +        (state == FORWARD_ZPU) || +        (state == FORWARD_ZPU_AND_XO) || +        (state == DROP_PACKET)) && (!fwd_input || in_tvalid); + +    assign {out_tlast,out_tuser,out_tdata} = fwd_input ?  {in_tlast,in_tuser,in_tdata} : header_ram[header_ram_addr]; + +    assign in_tready = (state == WAIT_PACKET) || +        (state == READ_HEADER) || +        (out_tready && fwd_input); + + +    // +    // Because we can forward to both the ZPU and XO FIFO's concurrently +    // we have to make sure both can accept data in the same cycle. +    // This makes it possible for either destination to block the other. +    // Make sure (both) destination(s) can accept data before passing it. +    // +    assign xo_pre_tvalid = out_tvalid && +        ((state == FORWARD_XO) || +        ((state == FORWARD_ZPU_AND_XO) && zpu_pre_tready)); +    assign zpu_pre_tvalid = out_tvalid && +        ((state == FORWARD_ZPU) || +        ((state == FORWARD_ZPU_AND_XO) && xo_pre_tready)); +    assign vita_pre_tvalid = out_tvalid && (state == FORWARD_RADIO_CORE); + +    assign {zpu_pre_tuser,zpu_pre_tdata} = ((state == FORWARD_ZPU_AND_XO) || (state == FORWARD_ZPU)) ? +        {out_tuser,out_tdata} : 0; + +    assign {xo_pre_tuser,xo_pre_tdata} = ((state == FORWARD_ZPU_AND_XO) || (state == FORWARD_XO)) ? +        {out_tuser,out_tdata} : 0; + +    assign {vita_pre_tuser,vita_pre_tdata} = (state == FORWARD_RADIO_CORE) ? {out_tuser,out_tdata} : 0; + +    assign zpu_pre_tlast = out_tlast && ((state == FORWARD_ZPU) || (state == FORWARD_ZPU_AND_XO)); + +    assign xo_pre_tlast =  out_tlast && ((state == FORWARD_XO) || (state == FORWARD_ZPU_AND_XO)); + +    assign vita_pre_tlast = out_tlast && (state == FORWARD_RADIO_CORE); + +    // +    // Egress FIFO's (Large) +    // +    axi_fifo #(.WIDTH(69),.SIZE(10)) +    axi_fifo_zpu ( +        .clk(clk), +        .reset(reset), +        .clear(clear), +        .i_tdata({zpu_pre_tlast,zpu_pre_tuser,zpu_pre_tdata}), +        .i_tvalid(zpu_pre_tvalid), +        .i_tready(zpu_pre_tready), +        .o_tdata({zpu_tlast,zpu_tuser,zpu_tdata}), +        .o_tvalid(zpu_tvalid), +        .o_tready(zpu_tready), +        .space(), +        .occupied() +    ); + +    axi_fifo #(.WIDTH(69),.SIZE(10)) +    axi_fifo_xo ( +        .clk(clk), +        .reset(reset), +        .clear(clear), +        .i_tdata({xo_pre_tlast,xo_pre_tuser,xo_pre_tdata}), +        .i_tvalid(xo_pre_tvalid), +        .i_tready(xo_pre_tready), +        .o_tdata({xo_tlast,xo_tuser,xo_tdata}), +        .o_tvalid(xo_tvalid), +        .o_tready(xo_tready), +        .space(), +        .occupied() +    ); + +    axi_fifo #(.WIDTH(69),.SIZE(10)) +    axi_fifo_vita ( +        .clk(clk), +        .reset(reset), +        .clear(clear), +        .i_tdata({vita_pre_tlast,vita_pre_tuser,vita_pre_tdata}), +        .i_tvalid(vita_pre_tvalid), +        .i_tready(vita_pre_tready), +        .o_tdata({vita_tlast,vita_tuser,vita_tdata}), +        .o_tvalid(vita_tvalid), +        .o_tready(vita_tready), +        .space(), +        .occupied() +    ); + +    assign debug_flags = {vita_pre_tready,xo_pre_tready,zpu_pre_tready}; + + +  /* -----\/----- EXCLUDED -----\/----- -    +     wire 	  vready, zready, oready;     wire 	  vvalid, zvalid, ovalid; -    +     reg [2:0] 	  ed_state;     localparam ED_IDLE     = 3'd0;     localparam ED_IN_HDR   = 3'd1; @@ -556,22 +555,22 @@ module eth_dispatch  	     ;         endcase // case (ed_state)     */ -    +  /* -----\/----- EXCLUDED -----\/-----     axi_packet_gate #(.WIDTH(64), .SIZE(10)) vita_gate       (.clk(clk), .reset(reset), .clear(clear),        .i_tdata(in_tdata), .i_tlast(), .i_terror(), .i_tvalid(1'b0), .i_tready(vready),        .o_tdata(vita_tdata), .o_tlast(vita_tlast), .o_tvalid(vita_tvalid), .o_tready(vita_tready)); -    +     axi_packet_gate #(.WIDTH(68), .SIZE(10)) zpu_gate       (.clk(clk), .reset(reset), .clear(clear),        .i_tdata({in_tuser,in_tdata}), .i_tlast(in_tlast), .i_terror(in_tuser[3]), .i_tvalid(in_tvalid), .i_tready(in_tready),        .o_tdata({zpu_tuser,zpu_tdata}), .o_tlast(zpu_tlast), .o_tvalid(zpu_tvalid), .o_tready(zpu_tready)); -    +     axi_packet_gate #(.WIDTH(68), .SIZE(10)) out_gate       (.clk(clk), .reset(reset), .clear(clear),        .i_tdata({in_tuser,in_tdata}), .i_tlast(), .i_terror(), .i_tvalid(1'b0), .i_tready(oready),        .o_tdata({out_tuser,out_tdata}), .o_tlast(out_tlast), .o_tvalid(out_tvalid), .o_tready(out_tready));   -----/\----- EXCLUDED -----/\----- */ -    +  endmodule // eth_dispatch diff --git a/fpga/usrp3/lib/vita/new_tx_control.v b/fpga/usrp3/lib/vita/new_tx_control.v index 4cdb54a24..910cc1f83 100644 --- a/fpga/usrp3/lib/vita/new_tx_control.v +++ b/fpga/usrp3/lib/vita/new_tx_control.v @@ -4,26 +4,26 @@ module new_tx_control    #(parameter BASE=0)     (input clk, input reset, input clear,      input set_stb, input [7:0] set_addr, input [31:0] set_data, -     +      input [63:0] vita_time,      output reg ack_or_error,      output packet_consumed,      output [11:0] seqnum,      output reg [63:0] error_code,      output [31:0] sid, -     +      // From tx_deframer      input [175:0] sample_tdata,      input sample_tvalid,      output sample_tready, -     +      // To DSP Core -    output [31:0] sample,     +    output [31:0] sample,      output run,    input strobe, -     +      output [31:0] debug      ); -    +     wire [31:0] 	  sample1 = sample_tdata[31:0];     wire [31:0] 	  sample0 = sample_tdata[63:32];     wire [63:0] 	  send_time = sample_tdata[127:64]; @@ -33,39 +33,39 @@ module new_tx_control     wire 	  eob = sample_tdata[173];     wire 	  send_at = sample_tdata[174];     wire 	  odd = sample_tdata[175]; -    +     wire 	  now, early, late, too_early;     wire 	  policy_next_burst, policy_next_packet, policy_wait;     wire 	  clear_seqnum; -    +     setting_reg #(.my_addr(BASE), .width(3)) sr_error_policy       (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),        .in(set_data),.out({policy_next_burst,policy_next_packet,policy_wait}),.changed(clear_seqnum)); -   time_compare  +   time_compare       time_compare (.clk(clk), .reset(reset), .time_now(vita_time), .trigger_time(send_time),  		   .now(now), .early(early), .late(late), .too_early(too_early));     assign run = (state == ST_SAMP0) | (state == ST_SAMP1); -    +     assign sample = (state == ST_SAMP0) ? sample0 : sample1; -    +     reg [2:0] 	 state; -    +     localparam ST_IDLE  = 0;     localparam ST_SAMP0 = 1;     localparam ST_SAMP1 = 2;     localparam ST_ERROR = 3;     localparam ST_WAIT  = 4; +   reg [11:0]  expected_seqnum; +     wire [63:0] CODE_EOB_ACK            = {32'd1,20'd0,seqnum};     wire [63:0] CODE_UNDERRUN           = {32'd2,20'd0,seqnum}; -   wire [63:0] CODE_SEQ_ERROR          = {32'd4,20'd0,seqnum}; +   wire [63:0] CODE_SEQ_ERROR          = {32'd4,4'd0,expected_seqnum,4'd0,seqnum};     wire [63:0] CODE_TIME_ERROR         = {32'd8,20'd0,seqnum};     wire [63:0] CODE_UNDERRUN_MIDPKT    = {32'd16,20'd0,seqnum}; -   wire [63:0] CODE_SEQ_ERROR_MIDBURST = {32'd32,20'd0,seqnum}; - -   reg [11:0]  expected_seqnum; +   wire [63:0] CODE_SEQ_ERROR_MIDBURST = {32'd32,4'd0,expected_seqnum,4'd0,seqnum};     always @(posedge clk)       if(reset | clear | clear_seqnum) @@ -73,14 +73,14 @@ module new_tx_control       else         if(sample_tvalid & sample_tready & eop)  	 expected_seqnum <= seqnum + 12'd1; -    +     always @(posedge clk)       if(reset | clear)         begin  	  state <= ST_IDLE;  	  ack_or_error <= 1'b0;  	  error_code <= 64'd0; -       end      +       end       else         case(state)  	 ST_IDLE : @@ -151,7 +151,7 @@ module new_tx_control     assign sample_tready = (state == ST_ERROR) | (strobe & ( (state == ST_SAMP1) | ((state == ST_SAMP0) & eop & odd) ) );     assign packet_consumed = eop & sample_tvalid & sample_tready; -    +     assign debug = {  		   error_code[37:32], // [30:25]  		   error_code[11:0], // [24:13] @@ -168,5 +168,5 @@ module new_tx_control  		   state[2:0] //  [2:0]  		   }; -    +  endmodule // new_tx_control  | 
