132 lines
5.1 KiB
Verilog
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
|