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