File: pcie_iop2_msg_arbiter.v

package info (click to toggle)
uhd 3.13.1.0-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 207,120 kB
  • sloc: cpp: 167,245; ansic: 86,841; vhdl: 53,420; python: 40,839; xml: 13,167; tcl: 5,688; makefile: 2,167; sh: 1,719; pascal: 230; csh: 94; asm: 20; perl: 11
file content (134 lines) | stat: -rw-r--r-- 5,326 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//
// Copyright 2013 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//


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