Files
b210-k7-fpga/lib/io_port2/pcie_iop2_msg_arbiter.v
T
Ben Hilburn fbbc991a7d Pushing the bulk of UHD-3.7.0 code.
Original-commit: ff1546f8137f7f92bb250f685561b0c34cc0e053
2014-02-14 12:05:07 -08:00

132 lines
5.1 KiB
Verilog

//
// Copyright 2013 Ettus Research LLC
//
module pcie_iop2_msg_arbiter #(
parameter E0_ADDR = 20'h0,
parameter E0_MASK = 20'h0,
parameter E1_ADDR = 20'h0,
parameter E1_MASK = 20'h0,
parameter E2_ADDR = 20'h0,
parameter E2_MASK = 20'h0,
parameter E3_ADDR = 20'h0,
parameter E3_MASK = 20'h0
) (
//Clocks and resets
input clk,
input reset,
input [63:0] regi_tdata,
input regi_tvalid,
output regi_tready,
output [63:0] rego_tdata,
output rego_tvalid,
input rego_tready,
output [63:0] e0_regi_tdata,
output e0_regi_tvalid,
input e0_regi_tready,
input [63:0] e0_rego_tdata,
input e0_rego_tvalid,
output e0_rego_tready,
output [63:0] e1_regi_tdata,
output e1_regi_tvalid,
input e1_regi_tready,
input [63:0] e1_rego_tdata,
input e1_rego_tvalid,
output e1_rego_tready,
output [63:0] e2_regi_tdata,
output e2_regi_tvalid,
input e2_regi_tready,
input [63:0] e2_rego_tdata,
input e2_rego_tvalid,
output e2_rego_tready,
output [63:0] e3_regi_tdata,
output e3_regi_tvalid,
input e3_regi_tready,
input [63:0] e3_rego_tdata,
input e3_rego_tvalid,
output e3_rego_tready
);
//*******************************************************************************
// PCIe output message arbiter
//
axi_mux4 #(.PRIO(0), .WIDTH(64), .BUFFER(0)) rego_arbiter_mux (
.clk(clk), .reset(reset), .clear(1'b0),
.i0_tdata(e0_rego_tdata), .i0_tlast(e0_rego_tvalid), .i0_tvalid(e0_rego_tvalid), .i0_tready(e0_rego_tready),
.i1_tdata(e1_rego_tdata), .i1_tlast(e1_rego_tvalid), .i1_tvalid(e1_rego_tvalid), .i1_tready(e1_rego_tready),
.i2_tdata(e2_rego_tdata), .i2_tlast(e2_rego_tvalid), .i2_tvalid(e2_rego_tvalid), .i2_tready(e2_rego_tready),
.i3_tdata(e3_rego_tdata), .i3_tlast(e3_rego_tvalid), .i3_tvalid(e3_rego_tvalid), .i3_tready(e3_rego_tready),
.o_tdata(rego_tdata), .o_tlast(), .o_tvalid(rego_tvalid), .o_tready(rego_tready)
);
//
//*******************************************************************************
//*******************************************************************************
// PCIe input message arbiter
//
wire [63:0] regi_msg;
wire regi_rc;
wire [19:0] regi_addr;
wire e0_rego_rd, e1_rego_rd, e2_rego_rd, e3_rego_rd;
ioport2_msg_decode e0_rego_decoder (.message(e0_rego_tdata), .rd_request(e0_rego_rd));
ioport2_msg_decode e1_rego_decoder (.message(e1_rego_tdata), .rd_request(e1_rego_rd));
ioport2_msg_decode e2_rego_decoder (.message(e2_rego_tdata), .rd_request(e2_rego_rd));
ioport2_msg_decode e3_rego_decoder (.message(e3_rego_tdata), .rd_request(e3_rego_rd));
localparam DEST_E0 = 2'd0;
localparam DEST_E1 = 2'd1;
localparam DEST_E2 = 2'd2;
localparam DEST_E3 = 2'd3;
reg [1:0] regi_resp_dest;
wire [1:0] regi_req_dest, regi_dest;
assign regi_req_dest =
((regi_addr & E0_MASK) == E0_ADDR) ? DEST_E0 : (
((regi_addr & E1_MASK) == E1_ADDR) ? DEST_E1 : (
((regi_addr & E2_MASK) == E2_ADDR) ? DEST_E2 : (
((regi_addr & E3_MASK) == E3_ADDR) ? DEST_E3 : (
DEST_E0))));
//A response must be routed to the port with the last read request
always @(posedge clk) begin
if (reset)
regi_resp_dest <= DEST_E0; //Default 0
else if (e0_rego_tvalid & e0_rego_tready & e0_rego_rd)
regi_resp_dest <= DEST_E0;
else if (e1_rego_tvalid & e1_rego_tready & e1_rego_rd)
regi_resp_dest <= DEST_E1;
else if (e2_rego_tvalid & e2_rego_tready & e2_rego_rd)
regi_resp_dest <= DEST_E2;
else if (e3_rego_tvalid & e3_rego_tready & e3_rego_rd)
regi_resp_dest <= DEST_E3;
end
ioport2_msg_decode regi_decoder (
.message(regi_msg), .rd_response(regi_rc), .address(regi_addr));
//If request, get destination from msg.
//If response, get destination from last read location.
assign regi_dest = regi_rc ? regi_resp_dest : regi_req_dest;
axi_demux4 #(.ACTIVE_CHAN(4'b1111), .WIDTH(64), .BUFFER(0)) regi_arbiter_demux (
.clk(clk), .reset(reset), .clear(1'b0),
.header(regi_msg), .dest(regi_dest),
.i_tdata(regi_tdata), .i_tlast(regi_tvalid), .i_tvalid(regi_tvalid), .i_tready(regi_tready),
.o0_tdata(e0_regi_tdata), .o0_tlast(), .o0_tvalid(e0_regi_tvalid), .o0_tready(e0_regi_tready),
.o1_tdata(e1_regi_tdata), .o1_tlast(), .o1_tvalid(e1_regi_tvalid), .o1_tready(e1_regi_tready),
.o2_tdata(e2_regi_tdata), .o2_tlast(), .o2_tvalid(e2_regi_tvalid), .o2_tready(e2_regi_tready),
.o3_tdata(e3_regi_tdata), .o3_tlast(), .o3_tvalid(e3_regi_tvalid), .o3_tready(e3_regi_tready)
);
//
//*******************************************************************************
endmodule