fpga: updating b200 and x300 FPGA source code for latest images

Original-commit: 00711ba213dde8aa0a099d2b18d3da0a33e6af79
This commit is contained in:
Ben Hilburn
2014-05-14 11:42:19 -07:00
parent 8f1cfd55b1
commit 5a525c84f5
71 changed files with 117080 additions and 4101 deletions
+1
View File
@@ -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 \
))
+6 -3
View File
@@ -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;
+10 -7
View File
@@ -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
+26
View File
@@ -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
+453 -454
View File
@@ -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;
//
// State machine declarations
//
reg [2:0] state;
wire header_done = (header_ram_addr == HEADER_RAM_SIZE-1);
reg fwd_input;
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;
//
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());
//
// 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;
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 header_done = (header_ram_addr == HEADER_RAM_SIZE-1);
reg fwd_input;
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());
//
reg [63:0] in_tdata_reg;
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 out_tvalid;
wire out_tready;
wire out_tlast;
wire [3:0] out_tuser;
wire [63:0] out_tdata;
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());
//
// 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
//
// Packet Forwarding State machine.
//
//
// 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);
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;
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);
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
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);
//
// 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
//
// 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;
//
// 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)
assign {xo_pre_tuser,xo_pre_tdata} = ((state == FORWARD_ZPU_AND_XO) || (state == FORWARD_XO)) ?
{out_tuser,out_tdata} : 0;
//
// 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};
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
+20 -20
View File
@@ -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