aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/io_port2/pcie_basic_regs.v
blob: e3790e81cedcf7c37e7fe9ee85f0443eb54a42c5 (plain)
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
//
// Copyright 2013 Ettus Research LLC
//


module pcie_basic_regs (
    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,
    
    input [31:0]    misc_status
);
    localparam PCIE_FPGA_SIG_VAL                = 32'h58333030; //X300 (ASCII)
    localparam PCIE_FPGA_COUNTER_FREQ           = 32'h0A6E49C0; //175MHz

    localparam PCIE_REG_ADDR_MASK               = 20'h001FF;

    localparam PCIE_FPGA_SIG_REG_ADDR           = 20'h00000;    //32-bit
    localparam PCIE_FPGA_COUNTER_LO_REG_ADDR    = 20'h00004;    //32-bit
    localparam PCIE_FPGA_COUNTER_HI_REG_ADDR    = 20'h00008;    //32-bit
    localparam PCIE_FPGA_COUNTER_FREQ_ADDR      = 20'h0000C;    //32-bit
    localparam PCIE_FPGA_SCRATCH0_ADDR          = 20'h00010;    //32-bit
    localparam PCIE_FPGA_SCRATCH1_ADDR          = 20'h00014;    //32-bit
    localparam PCIE_FPGA_MISC_STATUS_ADDR       = 20'h00020;    //32-bit
    localparam PCIE_FPGA_USR_SIG_REG_ADDR       = 20'h00030;    //128-bit

    wire            regi_wr, regi_rd;
    wire [19:0]     regi_addr, regi_addr_local;
    wire [31:0]     regi_payload;
    reg  [31:0]     rego_payload;

    ioport2_msg_decode regi_decoder (
        .message(regi_tdata), .wr_request(regi_wr), .rd_request(regi_rd),
        .address(regi_addr), .data(regi_payload)
    );

    ioport2_msg_encode  rego_encoder (
        .rd_response(1'b1), .data(rego_payload), .message(rego_tdata)
    );

    assign regi_tready = (regi_tvalid & regi_wr) | rego_tready;
    assign rego_tvalid = regi_tvalid & regi_rd;
    assign regi_addr_local = regi_addr & PCIE_REG_ADDR_MASK;

    //Counter counting bus_clk cycles
    reg [63:0]  bus_counter;
    always @(posedge clk) begin
        if (reset)  bus_counter <= 64'h0;
        else        bus_counter <= bus_counter + 1;
    end

    //Scratch registers
    reg [63:0]  scratch;
    always @(posedge clk) begin
        if (reset)  
            scratch <= 64'h0;
        else if (regi_tvalid & regi_tready & regi_wr)
            if (regi_addr_local == PCIE_FPGA_SCRATCH0_ADDR)
                scratch[31:0]  <= regi_payload;
            else if (regi_addr_local == PCIE_FPGA_SCRATCH1_ADDR)
                scratch[63:32] <= regi_payload;
    end
    
    //User signature register
    reg [127:0]  usr_signature;
    always @(posedge clk) begin
        if (reset)
            usr_signature <= 128'h0;
        else if (regi_tvalid & regi_tready & regi_wr)
            if (regi_addr_local == (PCIE_FPGA_USR_SIG_REG_ADDR + 20'h00000))
                usr_signature[31:0]  <= regi_payload;
            else if (regi_addr_local == (PCIE_FPGA_USR_SIG_REG_ADDR + 20'h00004))
                usr_signature[63:32]  <= regi_payload;
            else if (regi_addr_local == (PCIE_FPGA_USR_SIG_REG_ADDR + 20'h00008))
                usr_signature[95:64]  <= regi_payload;
            else if (regi_addr_local == (PCIE_FPGA_USR_SIG_REG_ADDR + 20'h0000C))
                usr_signature[127:96]  <= regi_payload;
    end

    always @(*) begin
        case (regi_addr_local)
            PCIE_FPGA_SIG_REG_ADDR:                 rego_payload = PCIE_FPGA_SIG_VAL;
            PCIE_FPGA_COUNTER_LO_REG_ADDR:          rego_payload = bus_counter[31:0];
            PCIE_FPGA_COUNTER_HI_REG_ADDR:          rego_payload = bus_counter[63:32];
            PCIE_FPGA_COUNTER_FREQ_ADDR:            rego_payload = PCIE_FPGA_COUNTER_FREQ;
            PCIE_FPGA_SCRATCH0_ADDR:                rego_payload = scratch[31:0];
            PCIE_FPGA_SCRATCH1_ADDR:                rego_payload = scratch[63:32];
            PCIE_FPGA_MISC_STATUS_ADDR:             rego_payload = misc_status;
            PCIE_FPGA_USR_SIG_REG_ADDR + 20'h00000: rego_payload = usr_signature[31:0];
            PCIE_FPGA_USR_SIG_REG_ADDR + 20'h00004: rego_payload = usr_signature[63:32];
            PCIE_FPGA_USR_SIG_REG_ADDR + 20'h00008: rego_payload = usr_signature[95:64];
            PCIE_FPGA_USR_SIG_REG_ADDR + 20'h0000C: rego_payload = usr_signature[127:96];
            default:                                rego_payload = 32'hFFFFFFFF;
        endcase
    end

endmodule