1//
2// Copyright 2013 Ettus Research LLC
3// Copyright 2018 Ettus Research, a National Instruments Company
4//
5// SPDX-License-Identifier: LGPL-3.0-or-later
6//
7
8
9`timescale 500ps/1ps
10`define CHECK_VALUE(val, expected, report) \
11        if (val == expected) \
12            $display("%s...Passed",report); \
13        else \
14            $display("%s...FAILED!!! (Val=0x%x, Exp=0x%x)",report,val,expected); \
15
16module pcie_wb_reg_core_tb();
17    reg         clk = 0, reset = 1;
18    reg         wb_stb_i = 0;
19    reg         wb_we_i = 0;
20    reg  [15:0] wb_adr_i = 0;
21    reg  [31:0] wb_dat_i = 0;
22    wire        wb_ack_o;
23    wire [31:0] wb_dat_o;
24
25    wire [63:0] msgo_data;
26    wire        msgo_valid;
27    reg         msgo_ready = 0;
28    reg  [63:0] msgi_data = 0;
29    reg         msgi_valid = 0;
30    wire        msgi_ready;
31
32    reg  [31:0] msgo_payload = 32'h0;
33    reg  [31:0] msgo_ctrl = 32'h0;
34
35    reg  [31:0] it;
36
37    always #10 clk = ~clk;
38
39    initial begin
40        #100 reset = 0;
41        #200000;
42        $finish;
43    end
44
45    localparam READ     = 3'b001;
46    localparam WRITE    = 3'b010;
47    localparam RESPONSE = 3'b100;
48
49    task pcie_send;
50        input [2:0]     op;
51        input [19:0]    address;
52        input [31:0]    data;
53    begin
54        //{rd_resp, wr_request, rd_request, half_word, 8'h00, address, data};
55        msgi_data  <= {op, 1'b0, 8'h00, address, data};
56        msgi_valid <= 1'b1;
57
58        @(posedge clk);
59        while (~msgi_ready) @(posedge clk);
60
61        msgi_valid <= 1'b0;
62        @(posedge clk);
63    end
64    endtask // pcie_send
65
66    task pcie_recv;
67        input [2:0]     op;
68        input [19:0]    address;
69        input [31:0]    data;
70    begin
71        while (~msgo_valid) @(posedge clk);
72
73        msgo_ready <= 1'b1;
74        @(posedge clk);
75
76        if (msgo_data[63] == op[2] || (msgo_data[62:61] == op[1:0] && msgo_data[51:32] == address))
77            msgo_payload <= msgo_data[31:0];
78            msgo_ctrl <= msgo_data[63:32];
79
80        msgo_ready <= 1'b0;
81        @(posedge clk);
82    end
83    endtask // pcie_recv
84
85    task wb_send;
86        input [2:0]     op;
87        input [15:0]    address;
88        input [31:0]    data;
89    begin
90        wb_adr_i <= address;
91        wb_dat_i <= data;
92        wb_we_i <= op[1];
93        wb_stb_i <= 1'b1;
94
95        @(posedge clk);
96        while (~wb_ack_o) @(posedge clk);
97
98        wb_stb_i <= 1'b0;
99    end
100    endtask // pcie_send
101
102
103    initial begin
104        msgo_ready <= 1'b0;
105        msgi_valid <= 1'b0;
106        while (reset) @(posedge clk);
107        @(posedge clk);
108
109        $display("\n[TEST] ZPU Read from PCIe");
110        pcie_send(WRITE, 20'h6a000, 32'h0);
111        `CHECK_VALUE(msgo_payload, 32'h0, "Verify PCIe readback before initiating read request");
112        pcie_send(READ, 20'h6a000, 32'h0);
113        pcie_recv(RESPONSE, 20'h0, 20'h0);
114        `CHECK_VALUE(msgo_payload, 32'h1, "Verify PCIe status after initiating read");
115        pcie_send(READ, 20'h6a000, 32'h0);
116        pcie_recv(RESPONSE, 20'h0, 20'h0);
117        `CHECK_VALUE(msgo_payload, 32'h1, "Verify PCIe status after initiating second read");
118        wb_send(READ, 16'hC, 32'h0);
119        `CHECK_VALUE(wb_dat_o, 32'h6, "Verify WB status after PCIe read request");
120        wb_send(READ, 16'h4, 32'h0);
121        `CHECK_VALUE(wb_dat_o, 32'h2000a000, "Verify WB control value after PCIe read request");
122        wb_send(READ, 16'hC, 32'h0);
123        `CHECK_VALUE(wb_dat_o, 32'h4, "Verify WB status value after consuming PCIe read request");
124        pcie_send(READ, 20'h6a000, 32'h0);
125        pcie_recv(RESPONSE, 20'h0, 20'h0);
126        `CHECK_VALUE(msgo_payload, 32'h1, "Verify PCIe status after WB consumes request only");
127        wb_send(WRITE, 16'h0, 32'hDEADBEEF);
128        wb_send(WRITE, 16'h4, 32'h80000000);
129        wb_send(READ, 16'hC, 32'h0);
130        `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after responding to PCIe read request");
131        pcie_send(READ, 20'h6a000, 32'h0);
132        pcie_recv(RESPONSE, 20'h0, 20'h0);
133        `CHECK_VALUE(msgo_payload, 32'h0, "Verify PCIe status after WB responds to read request");
134        pcie_send(READ, 20'h7a000, 32'h0);
135        pcie_recv(RESPONSE, 20'h0, 20'h0);
136        `CHECK_VALUE(msgo_payload, 32'hdeadbeef, "Verify PCIe read data");
137
138        $display("\n[TEST] ZPU Write from PCIe");
139        pcie_send(WRITE, 20'h7b000, 32'h12345678);
140        pcie_send(READ, 20'h7a000, 32'h0);
141        pcie_recv(RESPONSE, 20'h0, 20'h0);
142        `CHECK_VALUE(msgo_payload, 32'hdeadbeef, "Verify that PCIe read data is still intact after write");
143        wb_send(READ, 16'hC, 32'h0);
144        `CHECK_VALUE(wb_dat_o, 32'h2, "Verify WB status value after PCIe write request");
145        wb_send(READ, 16'h0, 32'h0);
146        `CHECK_VALUE(wb_dat_o, 32'h12345678, "Verify WB data value after PCIe read request");
147        wb_send(READ, 16'h4, 32'h0);
148        `CHECK_VALUE(wb_dat_o, 32'h4000b000, "Verify WB control value after PCIe read request");
149        wb_send(READ, 16'hC, 32'h0);
150        `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after consuming PCIe write request");
151        pcie_send(READ, 20'h6a000, 32'h0);
152        pcie_recv(RESPONSE, 20'h0, 20'h0);
153        `CHECK_VALUE(msgo_payload, 32'h0, "Verify PCIe status after WB consumes request");
154
155        $display("\n[TEST] Chinch Write from ZPU");
156        wb_send(READ, 16'hC, 32'h0);
157        `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value before initiating write request");
158        wb_send(WRITE, 16'h0, 32'h00beef00);
159        wb_send(READ, 16'hC, 32'h0);
160        `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after writing just the data reg");
161        wb_send(WRITE, 16'h4, 32'h40000200);
162        wb_send(READ, 16'hC, 32'h0);
163        `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after initiating write");
164        pcie_recv(WRITE, 20'h200, 20'h0);
165        `CHECK_VALUE(msgo_payload, 32'h00beef00, "Verify received PCIe data");
166        `CHECK_VALUE(msgo_ctrl, 32'h40000200, "Verify received PCIe control");
167        wb_send(WRITE, 16'h0, 32'h00feeb00);
168        wb_send(WRITE, 16'h4, 32'h400002fc);
169        pcie_recv(WRITE, 20'h200, 20'h0);
170        `CHECK_VALUE(msgo_payload, 32'h00feeb00, "Verify second received PCIe data");
171        `CHECK_VALUE(msgo_ctrl, 32'h400002fc, "Verify second received PCIe control");
172
173        $display("\n[TEST] Chinch Read from ZPU");
174        wb_send(READ, 16'hC, 32'h0);
175        `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value before initiating read request");
176        wb_send(WRITE, 16'h0, 32'hffffffff);
177        wb_send(READ, 16'hC, 32'h0);
178        `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after writing just the data reg");
179        wb_send(WRITE, 16'h4, 32'h20000400);
180        wb_send(READ, 16'hC, 32'h0);
181        `CHECK_VALUE(wb_dat_o, 32'h1, "Verify WB status value after initiating read request");
182        pcie_recv(READ, 20'h400, 20'h0);
183        `CHECK_VALUE(msgo_payload, 32'hffffffff, "Verify received PCIe data");
184        `CHECK_VALUE(msgo_ctrl, 32'h20000400, "Verify received PCIe control");
185        wb_send(READ, 16'hC, 32'h0);
186        wb_send(READ, 16'hC, 32'h0);
187        `CHECK_VALUE(wb_dat_o, 32'h1, "Verify WB status value before PCIe responds");
188        pcie_send(RESPONSE, 20'h000, 32'hace06666);
189        wb_send(READ, 16'hC, 32'h0);
190        `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after PCIe responds");
191        wb_send(READ, 16'h8, 32'h0);
192        `CHECK_VALUE(wb_dat_o, 32'hace06666, "Verify WB read value after PCIe responds");
193
194        $display("\n[TEST] WB Outbound flood");
195        wb_send(READ, 16'hC, 32'h0);
196        `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status before request flood");
197        for (it = 0; it < 64; it = it + 1) begin
198            wb_send(WRITE, 16'h4, 32'h20000400);
199        end
200        wb_send(READ, 16'hC, 32'h0);
201        `CHECK_VALUE(wb_dat_o, 32'h11, "Verify WB status after request flood");
202        for (it = 0; it < 64; it = it + 1) begin
203            pcie_recv(READ, 20'h400, 20'h0);
204        end
205        wb_send(READ, 16'hC, 32'h0);
206        `CHECK_VALUE(wb_dat_o, 32'h1, "Verify WB status after consuming requests");
207
208        $display("\n[TEST] PCIe Transaction Status");
209        pcie_send(READ, 20'h6a000, 32'h0);
210        pcie_recv(RESPONSE, 20'h0, 20'h0);
211        `CHECK_VALUE(msgo_payload, 32'h0, "Verify PCIe status before multiple reads");
212        pcie_send(WRITE, 20'h6a000, 32'h0);
213        pcie_send(WRITE, 20'h6a000, 32'h0);
214        pcie_send(WRITE, 20'h6a000, 32'h0);
215        pcie_send(READ, 20'h6a000, 32'h0);
216        pcie_recv(RESPONSE, 20'h0, 20'h0);
217        pcie_send(READ, 20'h6a000, 32'h0);
218        pcie_recv(RESPONSE, 20'h0, 20'h0);
219        pcie_send(READ, 20'h6a000, 32'h0);
220        pcie_recv(RESPONSE, 20'h0, 20'h0);
221        `CHECK_VALUE(msgo_payload, 32'h1, "Verify PCIe status before multiple read requests and status queries");
222        wb_send(READ, 16'h4, 32'h0);
223        wb_send(WRITE, 16'h0, 32'hDEADBEEF);
224        wb_send(WRITE, 16'h4, 32'h80000000);
225        pcie_send(READ, 20'h6a000, 32'h0);
226        pcie_recv(RESPONSE, 20'h0, 20'h0);
227        `CHECK_VALUE(msgo_payload, 32'h0, "Verify PCIe status after response");
228
229        $display("\n[DONE]");
230
231
232    end // initial begin
233
234    pcie_wb_reg_core #(.WB_ADDRW(16), .WB_DATAW(32)) dut (
235        .clk(clk), .rst(reset),
236        .wb_stb_i(wb_stb_i), .wb_we_i(wb_we_i), .wb_adr_i(wb_adr_i),
237        .wb_dat_i(wb_dat_i), .wb_ack_o(wb_ack_o), .wb_dat_o(wb_dat_o),
238        .msgi_tdata(msgi_data), .msgi_tvalid(msgi_valid), .msgi_tready(msgi_ready),
239        .msgo_tdata(msgo_data), .msgo_tvalid(msgo_valid), .msgo_tready(msgo_ready),
240        .debug());
241
242
243endmodule
244