mirror of
https://github.com/fairwaves/UHD-Fairwaves.git
synced 2025-10-23 07:42:00 +00:00
umtrx: work on wider router and dispatcher + fw changes to match -- not tested
This commit is contained in:
@@ -51,6 +51,7 @@ u2plus_core.v \
|
||||
umtrx_tx_chain.v \
|
||||
umtrx_rx_chain.v \
|
||||
umtrx_router.v \
|
||||
umtrx_packet_dispatcher.v \
|
||||
coregen/chipscope_icon.v \
|
||||
coregen/chipscope_icon.xco \
|
||||
coregen/chipscope_ila.v \
|
||||
|
@@ -353,7 +353,7 @@ module u2plus_core
|
||||
wire dsp_tx0_ready, dsp_tx0_valid;
|
||||
wire dsp_tx1_ready, dsp_tx1_valid;
|
||||
wire eth_tx_ready, eth_tx_valid;
|
||||
wire [35:0] dsp_tx_data, eth_tx_data;
|
||||
wire [35:0] dsp_tx0_data, dsp_tx1_data, eth_tx_data;
|
||||
|
||||
wire dsp_rx0_valid, dsp_rx0_ready;
|
||||
wire eth_rx_valid, eth_rx_ready;
|
||||
@@ -365,29 +365,35 @@ module u2plus_core
|
||||
wire [35:0] err_tx1_data;
|
||||
wire err_tx1_valid, err_tx1_ready;
|
||||
|
||||
wire [31:0] router_debug;
|
||||
umtrx_router #(.BUF_SIZE(9), .UDP_BASE(SR_UDP_SM), .CTRL_BASE(SR_BUF_POOL)) router
|
||||
(
|
||||
.wb_clk_i(wb_clk),.wb_rst_i(wb_rst),
|
||||
.wb_we_i(s1_we),.wb_stb_i(s1_stb),.wb_adr_i(s1_adr),.wb_dat_i(s1_dat_o),
|
||||
.wb_dat_o(s1_dat_i),.wb_ack_o(s1_ack),.wb_err_o(),.wb_rty_o(),
|
||||
|
||||
umtrx_router #(.BUF_SIZE(9), .UDP_BASE(SR_UDP_SM), .CTRL_BASE(SR_BUF_POOL)) router
|
||||
(.wb_clk_i(wb_clk),.wb_rst_i(wb_rst),
|
||||
.wb_we_i(s1_we),.wb_stb_i(s1_stb),.wb_adr_i(s1_adr),.wb_dat_i(s1_dat_o),
|
||||
.wb_dat_o(s1_dat_i),.wb_ack_o(s1_ack),.wb_err_o(),.wb_rty_o(),
|
||||
.set_stb(set_stb_sys), .set_addr(set_addr_sys), .set_data(set_data_sys),
|
||||
|
||||
.set_stb(set_stb_sys), .set_addr(set_addr_sys), .set_data(set_data_sys),
|
||||
.stream_clk(sys_clk), .stream_rst(sys_rst), .stream_clr(1'b0),
|
||||
|
||||
.stream_clk(sys_clk), .stream_rst(sys_rst), .stream_clr(1'b0),
|
||||
.status(status),
|
||||
|
||||
.status(status), .debug(router_debug),
|
||||
.eth_inp_data(eth_rx_data), .eth_inp_valid(eth_rx_valid), .eth_inp_ready(eth_rx_ready),
|
||||
.eth_out_data(eth_tx_data), .eth_out_valid(eth_tx_valid), .eth_out_ready(eth_tx_ready),
|
||||
|
||||
.dsp0_inp_data(dsp_rx0_data), .dsp0_inp_valid(dsp_rx0_valid), .dsp0_inp_ready(dsp_rx0_ready),
|
||||
.dsp1_inp_data(dsp_rx1_data), .dsp1_inp_valid(dsp_rx1_valid), .dsp1_inp_ready(dsp_rx1_ready),
|
||||
.eth_inp_data(eth_rx_data), .eth_inp_valid(eth_rx_valid), .eth_inp_ready(eth_rx_ready),
|
||||
.err_inp_data(err_tx0_data), .err_inp_ready(err_tx0_ready), .err_inp_valid(err_tx0_valid),
|
||||
.ctrl_inp_data(), .ctrl_inp_valid(1'b0), .ctrl_inp_ready(),
|
||||
.dsp0_inp_data(dsp_rx0_data), .dsp0_inp_valid(dsp_rx0_valid), .dsp0_inp_ready(dsp_rx0_ready),
|
||||
.dsp1_inp_data(dsp_rx1_data), .dsp1_inp_valid(dsp_rx1_valid), .dsp1_inp_ready(dsp_rx1_ready),
|
||||
.err0_inp_data(err_tx0_data), .err0_inp_valid(err_tx0_valid), .err0_inp_ready(err_tx0_ready),
|
||||
.err1_inp_data(err_tx1_data), .err1_inp_valid(err_tx1_valid), .err1_inp_ready(err_tx1_ready),
|
||||
.err2_inp_data(), .err2_inp_valid(1'b0), .err2_inp_ready(),
|
||||
.err3_inp_data(), .err3_inp_valid(1'b0), .err3_inp_ready(),
|
||||
|
||||
.dsp_out_data(dsp_tx_data), .dsp_out_valid(dsp_tx0_valid), .dsp_out_ready(dsp_tx0_ready),
|
||||
.dsp1_out_valid(dsp_tx1_valid), .dsp1_out_ready(dsp_tx1_ready),
|
||||
.err_inp1_data(err_tx1_data), .err_inp1_ready(err_tx1_ready), .err_inp1_valid(err_tx1_valid),
|
||||
.eth_out_data(eth_tx_data), .eth_out_valid(eth_tx_valid), .eth_out_ready(eth_tx_ready)
|
||||
);
|
||||
.ctrl_out_data(), .ctrl_out_valid(), .ctrl_out_ready(1'b1),
|
||||
.dsp0_out_data(dsp_tx0_data), .dsp0_out_valid(dsp_tx0_valid), .dsp0_out_ready(dsp_tx0_ready),
|
||||
.dsp1_out_data(dsp_tx1_data), .dsp1_out_valid(dsp_tx1_valid), .dsp1_out_ready(dsp_tx1_ready),
|
||||
.dsp2_out_data(), .dsp2_out_valid(), .dsp2_out_ready(1'b1),
|
||||
.dsp3_out_data(), .dsp3_out_valid(), .dsp3_out_ready(1'b1)
|
||||
);
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
// SPI -- Slave #2
|
||||
@@ -701,7 +707,7 @@ module u2plus_core
|
||||
.RAM_OEn(),
|
||||
.RAM_CE1n(),
|
||||
`endif // !`ifndef NO_EXT_FIFO
|
||||
.datain(dsp_tx_data),
|
||||
.datain(dsp_tx0_valid?dsp_tx0_data:dsp_tx1_data),
|
||||
.src_rdy_i(dsp_tx0_valid),
|
||||
.dst_rdy_o(dsp_tx0_ready),
|
||||
.dataout(sram0_data),
|
||||
|
207
fpga/top/UmTRX/umtrx_packet_dispatcher.v
Normal file
207
fpga/top/UmTRX/umtrx_packet_dispatcher.v
Normal file
@@ -0,0 +1,207 @@
|
||||
//
|
||||
// Copyright 2011-2012 Ettus Research LLC
|
||||
//
|
||||
// Packet dispatcher with fifo36 interface and 4 outputs.
|
||||
//
|
||||
// The packet dispatcher expects 2-byte padded ethernet frames.
|
||||
// The frames will be inspected at ethernet, IPv4, UDP, and VRT layers.
|
||||
//
|
||||
// The following registers are used for dispatcher control:
|
||||
// * base + 0 = this ipv4 address (32 bits)
|
||||
// * base + 1 = udp server port (lower 16 bits)
|
||||
//
|
||||
|
||||
module umtrx_packet_dispatcher
|
||||
#(
|
||||
parameter BASE = 0,
|
||||
parameter PORTS = 4,
|
||||
parameter DROP_INDEX = 0,
|
||||
parameter CPU_INDEX = 1
|
||||
)
|
||||
(
|
||||
//clocking and reset interface:
|
||||
input clk, input rst, input clr,
|
||||
|
||||
//setting register interface:
|
||||
input set_stb, input [7:0] set_addr, input [31:0] set_data,
|
||||
|
||||
//input stream interfaces:
|
||||
input [35:0] com_inp_data, input com_inp_valid, output com_inp_ready,
|
||||
|
||||
//output stream interfaces:
|
||||
output [35:0] pd_out_data, output pd_out_valid, input pd_out_ready, output reg [7:0] pd_dest
|
||||
);
|
||||
|
||||
//setting register to program the IP address
|
||||
wire [31:0] my_ip_addr;
|
||||
setting_reg #(.my_addr(BASE+0)) sreg_ip_addr(
|
||||
.clk(clk),.rst(rst),
|
||||
.strobe(set_stb),.addr(set_addr),.in(set_data),
|
||||
.out(my_ip_addr),.changed()
|
||||
);
|
||||
|
||||
//setting register to program the UDP DSP port
|
||||
wire [15:0] my_udp_port;
|
||||
setting_reg #(.my_addr(BASE+1), .width(16)) sreg_udp_port(
|
||||
.clk(clk),.rst(rst),
|
||||
.strobe(set_stb),.addr(set_addr),.in(set_data),
|
||||
.out(my_udp_port),.changed()
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Communication input inspector
|
||||
// - inspect com input and send it to DSP, EXT, CPU, or BOTH
|
||||
////////////////////////////////////////////////////////////////////
|
||||
localparam PD_STATE_READ_COM_PRE = 0;
|
||||
localparam PD_STATE_READ_COM = 1;
|
||||
localparam PD_STATE_WRITE_REGS = 2;
|
||||
localparam PD_STATE_WRITE_LIVE = 3;
|
||||
|
||||
localparam PD_MAX_NUM_DREGS = 14; //padded_eth + ip + udp + seq + vrt_hdr + vrt_sid
|
||||
localparam PD_DREGS_DSP_OFFSET = 11; //offset to start dsp at
|
||||
|
||||
reg [1:0] pd_state;
|
||||
reg [3:0] pd_dreg_count; //data registers to buffer headers
|
||||
wire [3:0] pd_dreg_count_next = pd_dreg_count + 1'b1;
|
||||
wire pd_dreg_counter_done = (pd_dreg_count_next == PD_MAX_NUM_DREGS)? 1'b1 : 1'b0;
|
||||
reg [35:0] pd_dregs [PD_MAX_NUM_DREGS-1:0];
|
||||
|
||||
reg is_eth_dst_mac_bcast;
|
||||
reg is_eth_type_ipv4;
|
||||
reg is_eth_ipv4_proto_udp;
|
||||
reg is_eth_ipv4_dst_addr_here;
|
||||
reg is_eth_udp_dst_port_here;
|
||||
reg is_eth_udp_ctl_port_here;
|
||||
reg is_vrt_size_zero;
|
||||
|
||||
//Inspector output flags special case:
|
||||
//Inject SOF into flags at first DSP line.
|
||||
wire [3:0] pd_out_flags = (
|
||||
(pd_dreg_count == PD_DREGS_DSP_OFFSET) &&
|
||||
(pd_dest != CPU_INDEX)
|
||||
)? 4'b0001 : pd_dregs[pd_dreg_count][35:32];
|
||||
|
||||
//The communication inspector ouput data and valid signals:
|
||||
//Mux between com input and data registers based on the state.
|
||||
assign pd_out_data = (pd_state == PD_STATE_WRITE_REGS)?
|
||||
{pd_out_flags, pd_dregs[pd_dreg_count][31:0]} : com_inp_data
|
||||
;
|
||||
assign pd_out_valid =
|
||||
(pd_state == PD_STATE_WRITE_REGS)? 1'b1 : (
|
||||
(pd_state == PD_STATE_WRITE_LIVE)? com_inp_valid : (
|
||||
1'b0));
|
||||
|
||||
//The communication inspector ouput ready signal:
|
||||
//Always ready when storing to data registers,
|
||||
//comes from inspector ready output when live,
|
||||
//and otherwise low.
|
||||
assign com_inp_ready =
|
||||
(pd_state == PD_STATE_READ_COM_PRE) ? 1'b1 : (
|
||||
(pd_state == PD_STATE_READ_COM) ? 1'b1 : (
|
||||
(pd_state == PD_STATE_WRITE_LIVE) ? pd_out_ready : (
|
||||
1'b0)));
|
||||
|
||||
//inspect the incoming data and mark register booleans
|
||||
always @(posedge clk)
|
||||
if (com_inp_ready & com_inp_valid) begin
|
||||
case(pd_dreg_count)
|
||||
0: begin
|
||||
is_eth_dst_mac_bcast <= (com_inp_data[15:0] == 16'hffff);
|
||||
end
|
||||
1: begin
|
||||
is_eth_dst_mac_bcast <= is_eth_dst_mac_bcast && (com_inp_data[31:0] == 32'hffffffff);
|
||||
end
|
||||
3: begin
|
||||
is_eth_type_ipv4 <= (com_inp_data[15:0] == 16'h800);
|
||||
end
|
||||
6: begin
|
||||
is_eth_ipv4_proto_udp <= (com_inp_data[23:16] == 8'h11);
|
||||
end
|
||||
8: begin
|
||||
is_eth_ipv4_dst_addr_here <= (com_inp_data[31:0] == my_ip_addr);
|
||||
end
|
||||
9: begin
|
||||
is_eth_udp_dst_port_here <= (com_inp_data[15:0] == my_udp_port);
|
||||
end
|
||||
12: begin
|
||||
is_vrt_size_zero <= (com_inp_data[15:0] == 16'h0);
|
||||
end
|
||||
endcase //pd_dreg_count
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
if(rst | clr) begin
|
||||
pd_state <= PD_STATE_READ_COM_PRE;
|
||||
pd_dreg_count <= 0;
|
||||
end
|
||||
else begin
|
||||
case(pd_state)
|
||||
PD_STATE_READ_COM_PRE: begin
|
||||
if (com_inp_ready & com_inp_valid & com_inp_data[32]) begin
|
||||
pd_state <= PD_STATE_READ_COM;
|
||||
pd_dreg_count <= pd_dreg_count_next;
|
||||
pd_dregs[pd_dreg_count] <= com_inp_data;
|
||||
end
|
||||
end
|
||||
|
||||
PD_STATE_READ_COM: begin
|
||||
if (com_inp_ready & com_inp_valid) begin
|
||||
pd_dregs[pd_dreg_count] <= com_inp_data;
|
||||
if (pd_dreg_counter_done | com_inp_data[33]) begin
|
||||
pd_state <= PD_STATE_WRITE_REGS;
|
||||
pd_dreg_count <= 0;
|
||||
|
||||
//---------- begin inspection decision -----------//
|
||||
//EOF or bcast or not IPv4 or not UDP:
|
||||
if (
|
||||
com_inp_data[33] || is_eth_dst_mac_bcast ||
|
||||
~is_eth_type_ipv4 || ~is_eth_ipv4_proto_udp
|
||||
) begin
|
||||
pd_dest <= CPU_INDEX;
|
||||
end
|
||||
|
||||
//UDP data port and VRT:
|
||||
else if (is_eth_ipv4_dst_addr_here && is_eth_udp_dst_port_here && ~is_vrt_size_zero) begin
|
||||
pd_dest <= com_inp_data[7:0];
|
||||
pd_dreg_count <= PD_DREGS_DSP_OFFSET;
|
||||
end
|
||||
|
||||
//other:
|
||||
else begin
|
||||
pd_dest <= DROP_INDEX;
|
||||
end
|
||||
//---------- end inspection decision -------------//
|
||||
|
||||
end
|
||||
else begin
|
||||
pd_dreg_count <= pd_dreg_count_next;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
PD_STATE_WRITE_REGS: begin
|
||||
if (pd_out_ready & pd_out_valid) begin
|
||||
if (pd_out_data[33]) begin
|
||||
pd_state <= PD_STATE_READ_COM_PRE;
|
||||
pd_dreg_count <= 0;
|
||||
end
|
||||
else if (pd_dreg_counter_done) begin
|
||||
pd_state <= PD_STATE_WRITE_LIVE;
|
||||
pd_dreg_count <= 0;
|
||||
end
|
||||
else begin
|
||||
pd_dreg_count <= pd_dreg_count_next;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
PD_STATE_WRITE_LIVE: begin
|
||||
if (pd_out_ready & pd_out_valid & pd_out_data[33]) begin
|
||||
pd_state <= PD_STATE_READ_COM_PRE;
|
||||
end
|
||||
end
|
||||
|
||||
endcase //pd_state
|
||||
end
|
||||
|
||||
endmodule // packet_dispatcher36_x3
|
@@ -44,21 +44,25 @@ module umtrx_router
|
||||
//output status register
|
||||
output [31:0] status,
|
||||
|
||||
output [31:0] debug,
|
||||
//eth interfaces
|
||||
input [35:0] eth_inp_data, input eth_inp_valid, output eth_inp_ready,
|
||||
output [35:0] eth_out_data, output eth_out_valid, input eth_out_ready,
|
||||
|
||||
// Input Interfaces (in to router)
|
||||
input [35:0] ctrl_inp_data, input ctrl_inp_valid, output ctrl_inp_ready,
|
||||
input [35:0] dsp0_inp_data, input dsp0_inp_valid, output dsp0_inp_ready,
|
||||
input [35:0] dsp1_inp_data, input dsp1_inp_valid, output dsp1_inp_ready,
|
||||
input [35:0] eth_inp_data, input eth_inp_valid, output eth_inp_ready,
|
||||
input [35:0] err_inp_data, input err_inp_valid, output err_inp_ready,
|
||||
input [35:0] ctl_inp_data, input ctl_inp_valid, output ctl_inp_ready,
|
||||
input [35:0] err0_inp_data, input err0_inp_valid, output err0_inp_ready,
|
||||
input [35:0] err1_inp_data, input err1_inp_valid, output err1_inp_ready,
|
||||
input [35:0] err2_inp_data, input err2_inp_valid, output err2_inp_ready,
|
||||
input [35:0] err3_inp_data, input err3_inp_valid, output err3_inp_ready,
|
||||
|
||||
// Output Interfaces (out of router)
|
||||
output [35:0] dsp_out_data, output dsp_out_valid, input dsp_out_ready,
|
||||
output dsp1_out_valid, input dsp1_out_ready,
|
||||
input [35:0] err_inp1_data, input err_inp1_valid, output err_inp1_ready,
|
||||
output [35:0] eth_out_data, output eth_out_valid, input eth_out_ready,
|
||||
output [35:0] ctl_out_data, output ctl_out_valid, input ctl_out_ready
|
||||
output [35:0] ctrl_out_data, output ctrl_out_valid, input ctrl_out_ready,
|
||||
output [35:0] dsp0_out_data, output dsp0_out_valid, input dsp0_out_ready,
|
||||
output [35:0] dsp1_out_data, output dsp1_out_valid, input dsp1_out_ready,
|
||||
output [35:0] dsp2_out_data, output dsp2_out_valid, input dsp2_out_ready,
|
||||
output [35:0] dsp3_out_data, output dsp3_out_valid, input dsp3_out_ready
|
||||
);
|
||||
|
||||
assign wb_err_o = 1'b0; // Unused for now
|
||||
@@ -103,57 +107,26 @@ module umtrx_router
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Communication output source combiner (feeds UDP proto machine)
|
||||
// - DSP input
|
||||
// - CPU input
|
||||
// - ERR input
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
//dummy signals to join the the muxes below
|
||||
wire [35:0] _combiner0_data, _combiner1_data;
|
||||
wire _combiner0_valid, _combiner1_valid;
|
||||
wire _combiner0_ready, _combiner1_ready;
|
||||
|
||||
wire [35:0] _combiner0_0_data;
|
||||
wire _combiner0_0_valid;
|
||||
wire _combiner0_0_ready;
|
||||
|
||||
fifo36_mux #(.prio(0)) // No priority, fair sharing
|
||||
_com_output_combiner0_0(
|
||||
axi_mux8 #(.WIDTH(36), .BUFFER(1)) combiner
|
||||
(
|
||||
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
|
||||
.data0_i(err_inp_data), .src0_rdy_i(err_inp_valid), .dst0_rdy_o(err_inp_ready),
|
||||
.data1_i(err_inp1_data), .src1_rdy_i(err_inp1_valid), .dst1_rdy_o(err_inp1_ready),
|
||||
.data_o(_combiner0_0_data), .src_rdy_o(_combiner0_0_valid), .dst_rdy_i(_combiner0_0_ready)
|
||||
);
|
||||
|
||||
fifo36_mux #(.prio(0)) // No priority, fair sharing
|
||||
_com_output_combiner0(
|
||||
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
|
||||
.data0_i(_combiner0_0_data), .src0_rdy_i(_combiner0_0_valid), .dst0_rdy_o(_combiner0_0_ready),
|
||||
.data1_i(cpu_inp_data), .src1_rdy_i(cpu_inp_valid), .dst1_rdy_o(cpu_inp_ready),
|
||||
.data_o(_combiner0_data), .src_rdy_o(_combiner0_valid), .dst_rdy_i(_combiner0_ready)
|
||||
);
|
||||
|
||||
fifo36_mux #(.prio(0)) // No priority, fair sharing
|
||||
_com_output_combiner1(
|
||||
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
|
||||
.data0_i(dsp0_inp_data), .src0_rdy_i(dsp0_inp_valid), .dst0_rdy_o(dsp0_inp_ready),
|
||||
.data1_i(dsp1_inp_data), .src1_rdy_i(dsp1_inp_valid), .dst1_rdy_o(dsp1_inp_ready),
|
||||
.data_o(_combiner1_data), .src_rdy_o(_combiner1_valid), .dst_rdy_i(_combiner1_ready)
|
||||
);
|
||||
|
||||
fifo36_mux #(.prio(1)) // Give priority to err/cpu over dsp
|
||||
com_output_source(
|
||||
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
|
||||
.data0_i(_combiner0_data), .src0_rdy_i(_combiner0_valid), .dst0_rdy_o(_combiner0_ready),
|
||||
.data1_i(_combiner1_data), .src1_rdy_i(_combiner1_valid), .dst1_rdy_o(_combiner1_ready),
|
||||
.data_o(com_out_data), .src_rdy_o(com_out_valid), .dst_rdy_i(com_out_ready)
|
||||
.i0_tdata(cpu_inp_data), .i0_tlast(cpu_inp_data[33]), .i0_tvalid(cpu_inp_valid), .i0_tready(cpu_inp_ready),
|
||||
.i1_tdata(ctrl_inp_data), .i1_tlast(ctrl_inp_data[33]), .i1_tvalid(ctrl_inp_valid), .i1_tready(ctrl_inp_ready),
|
||||
.i2_tdata(dsp0_inp_data), .i2_tlast(dsp0_inp_data[33]), .i2_tvalid(dsp0_inp_valid), .i2_tready(dsp0_inp_ready),
|
||||
.i3_tdata(dsp1_inp_data), .i3_tlast(dsp1_inp_data[33]), .i3_tvalid(dsp1_inp_valid), .i3_tready(dsp1_inp_ready),
|
||||
.i4_tdata(err0_inp_data), .i4_tlast(err0_inp_data[33]), .i4_tvalid(err0_inp_valid), .i4_tready(err0_inp_ready),
|
||||
.i5_tdata(err1_inp_data), .i5_tlast(err1_inp_data[33]), .i5_tvalid(err1_inp_valid), .i5_tready(err1_inp_ready),
|
||||
.i6_tdata(err2_inp_data), .i6_tlast(err2_inp_data[33]), .i6_tvalid(err2_inp_valid), .i6_tready(err2_inp_ready),
|
||||
.i7_tdata(err3_inp_data), .i7_tlast(err3_inp_data[33]), .i7_tvalid(err3_inp_valid), .i7_tready(err3_inp_ready),
|
||||
.o_tdata(com_out_data), .o_tlast(), .o_tvalid(com_out_valid), .o_tready(com_out_ready)
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Interface CPU to memory mapped wishbone
|
||||
// - Uses 1 setting register
|
||||
////////////////////////////////////////////////////////////////////
|
||||
buffer_int2 #(.BASE(CTRL_BASE+3), .BUF_SIZE(BUF_SIZE)) cpu_to_wb(
|
||||
buffer_int2 #(.BASE(CTRL_BASE), .BUF_SIZE(BUF_SIZE)) cpu_to_wb(
|
||||
.clk(stream_clk), .rst(stream_rst | stream_clr),
|
||||
.set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
|
||||
.status(cpu_iface_status),
|
||||
@@ -174,21 +147,36 @@ module umtrx_router
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Packet Dispatcher
|
||||
// - Uses 2 setting registers
|
||||
// - provide buffering before cpu for random + small packet bursts
|
||||
////////////////////////////////////////////////////////////////////
|
||||
wire [35:0] _cpu_out_data;
|
||||
wire _cpu_out_valid;
|
||||
wire _cpu_out_ready;
|
||||
|
||||
packet_dispatcher36_x3 #(.BASE(CTRL_BASE+1)) packet_dispatcher(
|
||||
wire [7:0] pd_dest;
|
||||
wire [35:0] pd_out_data;
|
||||
wire pd_out_valid, pd_out_ready;
|
||||
|
||||
umtrx_packet_dispatcher #(.BASE(CTRL_BASE+1), .PORTS(7), .DROP_INDEX(7), .CPU_INDEX(0)) packet_dispatcher(
|
||||
.clk(stream_clk), .rst(stream_rst), .clr(stream_clr),
|
||||
.set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
|
||||
.com_inp_data(com_inp_data), .com_inp_valid(com_inp_valid), .com_inp_ready(com_inp_ready),
|
||||
.ext_out_data(), .ext_out_valid(), .ext_out_ready(1'b1),
|
||||
.dsp_out_data(dsp_out_data), .dsp_out_valid(dsp_out_valid), .dsp_out_ready(dsp_out_ready),
|
||||
.dsp1_out_valid(dsp1_out_valid), .dsp1_out_ready(dsp1_out_ready),
|
||||
.cpu_out_data(_cpu_out_data), .cpu_out_valid(_cpu_out_valid), .cpu_out_ready(_cpu_out_ready)
|
||||
.pd_out_data(pd_out_data), .pd_out_valid(pd_out_valid), .pd_out_ready(pd_out_ready), .pd_dest(pd_dest)
|
||||
);
|
||||
|
||||
axi_demux8 #(.WIDTH(36), .BUFFER(1)) splitter
|
||||
(
|
||||
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
|
||||
.header(), .dest(pd_dest[2:0]),
|
||||
.i_tdata(pd_out_data), .i_tlast(pd_out_data[33]), .i_tvalid(pd_out_valid), .i_tready(pd_out_ready),
|
||||
.o0_tdata(_cpu_out_data), .o0_tlast(), .o0_tvalid(_cpu_out_valid), .o0_tready(_cpu_out_ready),
|
||||
.o1_tdata(ctrl_out_data), .o1_tlast(), .o1_tvalid(ctrl_out_valid), .o1_tready(ctrl_out_ready),
|
||||
.o2_tdata(dsp0_out_data), .o2_tlast(), .o2_tvalid(dsp0_out_valid), .o2_tready(dsp0_out_ready),
|
||||
.o3_tdata(dsp1_out_data), .o3_tlast(), .o3_tvalid(dsp1_out_valid), .o3_tready(dsp1_out_ready),
|
||||
.o4_tdata(dsp2_out_data), .o4_tlast(), .o4_tvalid(dsp2_out_valid), .o4_tready(dsp2_out_ready),
|
||||
.o5_tdata(dsp3_out_data), .o5_tlast(), .o5_tvalid(dsp3_out_valid), .o5_tready(dsp3_out_ready),
|
||||
.o6_tdata(), .o6_tlast(), .o6_tvalid(), .o6_tready(1'b1),
|
||||
.o7_tdata(), .o7_tlast(), .o7_tvalid(), .o7_tready(1'b1)
|
||||
);
|
||||
|
||||
fifo_cascade #(.WIDTH(36), .SIZE(9/*512 lines plenty for short pkts*/)) cpu_out_fifo (
|
||||
@@ -200,39 +188,10 @@ module umtrx_router
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// UDP TX Protocol machine
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
prot_eng_tx #(.BASE(UDP_BASE)) udp_prot_eng_tx
|
||||
(.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
|
||||
.set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
|
||||
.datain(com_out_data), .src_rdy_i(com_out_valid), .dst_rdy_o(com_out_ready),
|
||||
.dataout(eth_out_data), .src_rdy_o(eth_out_valid), .dst_rdy_i(eth_out_ready) );
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Assign debugs
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
assign debug = {
|
||||
//inputs to the router (12)
|
||||
dsp0_inp_ready, dsp0_inp_valid,
|
||||
dsp1_inp_ready, dsp1_inp_valid,
|
||||
err_inp_ready, err_inp_valid,
|
||||
2'b0,
|
||||
eth_inp_ready, eth_inp_valid,
|
||||
cpu_inp_ready, cpu_inp_valid,
|
||||
|
||||
//outputs from the router (8)
|
||||
dsp_out_ready, dsp_out_valid,
|
||||
2'b0,
|
||||
eth_out_ready, eth_out_valid,
|
||||
cpu_out_ready, cpu_out_valid,
|
||||
|
||||
//other interfaces (8)
|
||||
2'b0,
|
||||
com_out_ready, com_out_valid,
|
||||
2'b0,
|
||||
com_inp_ready, com_inp_valid,
|
||||
|
||||
4'b0
|
||||
};
|
||||
|
||||
endmodule // umtrx_router
|
||||
|
@@ -48,6 +48,7 @@ typedef struct{
|
||||
// Dynamic and/or private ports: 49152-65535
|
||||
#define USRP2_UDP_CTRL_PORT 49152
|
||||
//#define USRP2_UDP_UPDATE_PORT 49154
|
||||
#define USRP2_UDP_SERVER_PORT 49156
|
||||
#define USRP2_UDP_RX_DSP0_PORT 49156
|
||||
#define USRP2_UDP_TX_DSP0_PORT 49157
|
||||
#define USRP2_UDP_RX_DSP1_PORT 49158
|
||||
|
@@ -313,13 +313,11 @@ void link_changed_callback(int speed){
|
||||
if (speed != 0){
|
||||
char led = speed==1000?LED_RJ45_ORANGE:LED_RJ45_GREEN;
|
||||
hal_set_leds(led, led);
|
||||
pkt_ctrl_set_routing_mode(PKT_CTRL_ROUTING_MODE_MASTER);
|
||||
send_gratuitous_arp();
|
||||
}
|
||||
else{
|
||||
hal_set_leds(0x0, LED_RJ45_ORANGE);
|
||||
hal_set_leds(0x0, LED_RJ45_GREEN);
|
||||
pkt_ctrl_set_routing_mode(PKT_CTRL_ROUTING_MODE_SLAVE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,7 +353,7 @@ main(void)
|
||||
|
||||
//1) register the addresses into the network stack
|
||||
register_addrs(ethernet_mac_addr(), get_ip_addr());
|
||||
pkt_ctrl_program_inspector(get_ip_addr(), USRP2_UDP_TX_DSP0_PORT, USRP2_UDP_TX_DSP1_PORT);
|
||||
pkt_ctrl_program_inspector(get_ip_addr(), USRP2_UDP_SERVER_PORT);
|
||||
|
||||
//2) register callbacks for udp ports we service
|
||||
init_udp_listeners();
|
||||
@@ -373,8 +371,8 @@ main(void)
|
||||
|
||||
udp_uart_init(USRP2_UDP_UART_BASE_PORT); //setup uart messaging
|
||||
|
||||
//3) set the routing mode to slave to set defaults
|
||||
pkt_ctrl_set_routing_mode(PKT_CTRL_ROUTING_MODE_SLAVE);
|
||||
//3) init input state
|
||||
pkt_ctrl_release_incoming_buffer();
|
||||
|
||||
//4) setup ethernet hardware to bring the link up
|
||||
ethernet_register_link_changed_callback(link_changed_callback);
|
||||
|
@@ -279,10 +279,9 @@ typedef struct {
|
||||
// --- packet router control regs ---
|
||||
|
||||
typedef struct {
|
||||
volatile uint32_t mode_ctrl;
|
||||
volatile uint32_t ip_addr;
|
||||
volatile uint32_t data_ports; //dsp0 (low 16) dsp1 (high 16)
|
||||
volatile uint32_t iface_ctrl;
|
||||
volatile uint32_t ip_addr;
|
||||
volatile uint32_t data_port; //lower 16
|
||||
} router_ctrl_t;
|
||||
|
||||
#define router_ctrl ((router_ctrl_t *) _SR_ADDR(SR_BUF_POOL))
|
||||
|
@@ -38,19 +38,10 @@
|
||||
#define CPU_CTRL_WR_START (1 << 3)
|
||||
|
||||
void pkt_ctrl_program_inspector(
|
||||
const struct ip_addr *ip_addr, uint16_t data_port0, uint16_t data_port1
|
||||
const struct ip_addr *ip_addr, uint16_t data_port
|
||||
){
|
||||
router_ctrl->ip_addr = ip_addr->addr;
|
||||
router_ctrl->data_ports = data_port0 | ((uint32_t)(data_port1) << 16);
|
||||
}
|
||||
|
||||
void pkt_ctrl_set_routing_mode(pkt_ctrl_routing_mode_t mode){
|
||||
//About to change the mode; ensure that we are accepting packets.
|
||||
//The plumbing will not switch if it cannot pass an end of packet.
|
||||
pkt_ctrl_release_incoming_buffer();
|
||||
|
||||
//Change the mode; this switches the valves and crossbars.
|
||||
router_ctrl->mode_ctrl = mode;
|
||||
router_ctrl->data_port = data_port;
|
||||
}
|
||||
|
||||
static inline void cpu_stat_wait_for(int bm){
|
||||
|
@@ -23,19 +23,11 @@
|
||||
#include <stdbool.h>
|
||||
#include <lwip/ip_addr.h>
|
||||
|
||||
typedef enum {
|
||||
PKT_CTRL_ROUTING_MODE_SLAVE = 0,
|
||||
PKT_CTRL_ROUTING_MODE_MASTER = 1
|
||||
} pkt_ctrl_routing_mode_t;
|
||||
|
||||
//! Program the decision values into the packet inspector
|
||||
void pkt_ctrl_program_inspector(
|
||||
const struct ip_addr *ip_addr, uint16_t data_port0, uint16_t data_port1
|
||||
const struct ip_addr *ip_addr, uint16_t data_port0
|
||||
);
|
||||
|
||||
//! Set the routing mode for this device
|
||||
void pkt_ctrl_set_routing_mode(pkt_ctrl_routing_mode_t mode);
|
||||
|
||||
/*!
|
||||
* Try to claim an incomming buffer.
|
||||
* \param num_lines filled with the buffer size
|
||||
|
Reference in New Issue
Block a user