diff options
Diffstat (limited to 'fpga/usrp3/lib/sim/io_port2')
3 files changed, 445 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/sim/io_port2/pcie_dma_ctrl/pcie_dma_ctrl_tb.v b/fpga/usrp3/lib/sim/io_port2/pcie_dma_ctrl/pcie_dma_ctrl_tb.v new file mode 100644 index 000000000..2b6c40bdd --- /dev/null +++ b/fpga/usrp3/lib/sim/io_port2/pcie_dma_ctrl/pcie_dma_ctrl_tb.v @@ -0,0 +1,92 @@ +// +// Copyright 2013 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + + +`timescale 500ps/1ps + +module pcie_dma_ctrl_tb(); + reg clk = 0; + reg reset = 1; + + always #10 clk = ~clk; + + initial begin + #100 reset = 0; + #200000; + $finish; + end + + function [63:0] iop2_msg_write; + input [19:0] address; + input [31:0] data; + input half_wd; + begin + // {rd_response, wr_request, rd_request, half_word, 8'h00, address, data}; + iop2_msg_write = {1'b0, 1'b1, 1'b0, half_wd, 8'h00, address, data}; + end + endfunction // iop2_msg_write + + function [63:0] iop2_msg_read; + input [19:0] address; + input half_wd; + begin + // {rd_response, wr_request, rd_request, half_word, 8'h00, address, data}; + iop2_msg_read = {1'b0, 1'b0, 1'b1, half_wd, 8'h00, address, 32'h0}; + end + endfunction // iop2_msg_read + + wire [3:0] clear; + wire [63:0] frame_size; + reg [3:0] pkt_stb = 0; + reg [3:0] samp_stb = 0; + reg [3:0] error = 0; + reg [7:0] rtr_sid = 4; + wire [3:0] rtr_dst; + + reg [63:0] regi_tdata; + reg regi_tvalid; + wire regi_tready; + wire [63:0] rego_tdata; + wire rego_tvalid; + reg rego_tready; + reg [31:0] rego_payload; + + always @(posedge clk) + if (rego_tdata[63] & rego_tvalid & rego_tready) + rego_payload <= rego_tdata[31:0]; + + initial begin + regi_tvalid <= 0; + rego_tready <= 0; + while (reset) @(posedge clk); + + rego_tready <= 1; + @(posedge clk); + + regi_tdata <= iop2_msg_write(20'h304, 32'hA, 0); + regi_tvalid <= 1; + @(posedge clk); + while (~regi_tready) @(posedge clk); + regi_tvalid <= 0; + @(posedge clk); + + end // initial begin + + pcie_dma_ctrl #( + .NUM_STREAMS(4), .FRAME_SIZE_W(16), + .REG_BASE_ADDR(20'h00200), .ENABLE_ROUTER(1), + .ROUTER_SID_W(8), .ROUTER_DST_W(4) + ) dut ( + .clk(clk), .reset(reset), + .regi_tdata(regi_tdata), .regi_tvalid(regi_tvalid), .regi_tready(regi_tready), + .rego_tdata(rego_tdata), .rego_tvalid(rego_tvalid), .rego_tready(rego_tready), + .set_clear(clear), .set_frame_size(frame_size), .sample_stb(samp_stb), .packet_stb(pkt_stb), + .stream_err(error), .rtr_sid(rtr_sid), .rtr_dst(rtr_dst) + ); + + +endmodule diff --git a/fpga/usrp3/lib/sim/io_port2/pcie_iop2_msg_arbiter/pcie_iop2_msg_arbiter_tb.v b/fpga/usrp3/lib/sim/io_port2/pcie_iop2_msg_arbiter/pcie_iop2_msg_arbiter_tb.v new file mode 100644 index 000000000..fe566b1aa --- /dev/null +++ b/fpga/usrp3/lib/sim/io_port2/pcie_iop2_msg_arbiter/pcie_iop2_msg_arbiter_tb.v @@ -0,0 +1,110 @@ +// +// Copyright 2013 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + + +`timescale 500ps/1ps + +module pcie_iop2_msg_arbiter_tb(); + reg clk = 0; + reg reset = 1; + + always #10 clk = ~clk; + + initial begin + #100 reset = 0; + #200000; + $finish; + end + + function [63:0] iop2_msg_write; + input [19:0] address; + input [31:0] data; + input half_wd; + begin + // {rd_response, wr_request, rd_request, half_word, 8'h00, address, data}; + iop2_msg_write = {1'b0, 1'b1, 1'b0, half_wd, 8'h00, address, data}; + end + endfunction // iop2_msg_write + + function [63:0] iop2_msg_read; + input [19:0] address; + input half_wd; + begin + // {rd_response, wr_request, rd_request, half_word, 8'h00, address, data}; + iop2_msg_read = {1'b0, 1'b0, 1'b1, half_wd, 8'h00, address, 32'h0}; + end + endfunction // iop2_msg_read + + reg [63:0] msgi_tdata; + wire [63:0] msgo_tdata; + wire msgo_tvalid, msgi_tready; + reg msgo_tready, msgi_tvalid; + + wire [63:0] basic_regi_tdata, zpu_regi_tdata; + wire basic_regi_tvalid, zpu_regi_tvalid; + reg basic_regi_tready, zpu_regi_tready; + reg [63:0] basic_rego_tdata, zpu_rego_tdata; + reg basic_rego_tvalid, zpu_rego_tvalid; + wire basic_rego_tready, zpu_rego_tready; + + initial begin + //@TODO: Make this a self-checking TB + while (reset) @(posedge clk); + + msgo_tready <= 1; + basic_regi_tready <= 1; + @(posedge clk); + + + msgi_tdata <= iop2_msg_write(20'h0, 32'hDEAD, 0); + msgi_tvalid <= 1; + while (~msgi_tready) @(posedge clk); + msgi_tvalid <= 0; + @(posedge clk); + + + msgi_tdata <= iop2_msg_read(20'h00000, 0); + msgi_tvalid <= 1; + while (~msgi_tready) @(posedge clk); + msgi_tvalid <= 0; + @(posedge clk); + + zpu_rego_tdata <= {1, 31'h0, 32'h12345678}; + zpu_rego_tvalid <= 1; + while (~zpu_rego_tready) @(posedge clk); + zpu_rego_tvalid <= 0; + + + + end // initial begin + + pcie_iop2_msg_arbiter #( + .E0_ADDR(20'h00000), .E0_MASK(20'hFFF00), //0x00000 - 0x000FF: Basic PCIe registers + .E1_ADDR(20'h00100), .E1_MASK(20'hFFF00), //0x00100 - 0x001FF: PCIe router registers + .E2_ADDR(20'h00200), .E2_MASK(20'hFFE00), //0x00200 - 0x003FF: DMA stream registers + .E3_ADDR(20'h40000), .E3_MASK(20'hC0000) //0x40000 - 0x7FFFF: Client address space + ) iop2_msg_arbiter ( + .clk(clk), .reset(reset), + //Master + .regi_tdata(msgi_tdata), .regi_tvalid(msgi_tvalid), .regi_tready(msgi_tready), + .rego_tdata(msgo_tdata), .rego_tvalid(msgo_tvalid), .rego_tready(msgo_tready), + //Endpoint 0 + .e0_regi_tdata(basic_regi_tdata), .e0_regi_tvalid(basic_regi_tvalid), .e0_regi_tready(basic_regi_tready), + .e0_rego_tdata(basic_rego_tdata), .e0_rego_tvalid(basic_rego_tvalid), .e0_rego_tready(basic_rego_tready), + //Endpoint 1 + .e1_regi_tdata(), .e1_regi_tvalid(), .e1_regi_tready(1'b1), + .e1_rego_tdata(64'h0), .e1_rego_tvalid(1'b0), .e1_rego_tready(), + //Endpoint 2 + .e2_regi_tdata(), .e2_regi_tvalid(), .e2_regi_tready(1'b1), + .e2_rego_tdata(64'h0), .e2_rego_tvalid(1'b0), .e2_rego_tready(), + //Endpoint 3 + .e3_regi_tdata(zpu_regi_tdata), .e3_regi_tvalid(zpu_regi_tvalid), .e3_regi_tready(zpu_regi_tready), + .e3_rego_tdata(zpu_rego_tdata), .e3_rego_tvalid(zpu_rego_tvalid), .e3_rego_tready(zpu_rego_tready) + ); + + +endmodule diff --git a/fpga/usrp3/lib/sim/io_port2/pcie_wb_reg_core/pcie_wb_reg_core_tb.v b/fpga/usrp3/lib/sim/io_port2/pcie_wb_reg_core/pcie_wb_reg_core_tb.v new file mode 100644 index 000000000..62bec9eb4 --- /dev/null +++ b/fpga/usrp3/lib/sim/io_port2/pcie_wb_reg_core/pcie_wb_reg_core_tb.v @@ -0,0 +1,243 @@ +// +// Copyright 2013 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + + +`timescale 500ps/1ps +`define CHECK_VALUE(val, expected, report) \ + if (val == expected) \ + $display("%s...Passed",report); \ + else \ + $display("%s...FAILED!!! (Val=0x%x, Exp=0x%x)",report,val,expected); \ + +module pcie_wb_reg_core_tb(); + reg clk = 0, reset = 1; + reg wb_stb_i = 0; + reg wb_we_i = 0; + reg [15:0] wb_adr_i = 0; + reg [31:0] wb_dat_i = 0; + wire wb_ack_o; + wire [31:0] wb_dat_o; + + wire [63:0] msgo_data; + wire msgo_valid; + reg msgo_ready = 0; + reg [63:0] msgi_data = 0; + reg msgi_valid = 0; + wire msgi_ready; + + reg [31:0] msgo_payload = 32'h0; + reg [31:0] msgo_ctrl = 32'h0; + + reg [31:0] it; + + always #10 clk = ~clk; + + initial begin + #100 reset = 0; + #200000; + $finish; + end + + localparam READ = 3'b001; + localparam WRITE = 3'b010; + localparam RESPONSE = 3'b100; + + task pcie_send; + input [2:0] op; + input [19:0] address; + input [31:0] data; + begin + //{rd_resp, wr_request, rd_request, half_word, 8'h00, address, data}; + msgi_data <= {op, 1'b0, 8'h00, address, data}; + msgi_valid <= 1'b1; + + @(posedge clk); + while (~msgi_ready) @(posedge clk); + + msgi_valid <= 1'b0; + @(posedge clk); + end + endtask // pcie_send + + task pcie_recv; + input [2:0] op; + input [19:0] address; + input [31:0] data; + begin + while (~msgo_valid) @(posedge clk); + + msgo_ready <= 1'b1; + @(posedge clk); + + if (msgo_data[63] == op[2] || (msgo_data[62:61] == op[1:0] && msgo_data[51:32] == address)) + msgo_payload <= msgo_data[31:0]; + msgo_ctrl <= msgo_data[63:32]; + + msgo_ready <= 1'b0; + @(posedge clk); + end + endtask // pcie_recv + + task wb_send; + input [2:0] op; + input [15:0] address; + input [31:0] data; + begin + wb_adr_i <= address; + wb_dat_i <= data; + wb_we_i <= op[1]; + wb_stb_i <= 1'b1; + + @(posedge clk); + while (~wb_ack_o) @(posedge clk); + + wb_stb_i <= 1'b0; + end + endtask // pcie_send + + + initial begin + msgo_ready <= 1'b0; + msgi_valid <= 1'b0; + while (reset) @(posedge clk); + @(posedge clk); + + $display("\n[TEST] ZPU Read from PCIe"); + pcie_send(WRITE, 20'h6a000, 32'h0); + `CHECK_VALUE(msgo_payload, 32'h0, "Verify PCIe readback before initiating read request"); + pcie_send(READ, 20'h6a000, 32'h0); + pcie_recv(RESPONSE, 20'h0, 20'h0); + `CHECK_VALUE(msgo_payload, 32'h1, "Verify PCIe status after initiating read"); + pcie_send(READ, 20'h6a000, 32'h0); + pcie_recv(RESPONSE, 20'h0, 20'h0); + `CHECK_VALUE(msgo_payload, 32'h1, "Verify PCIe status after initiating second read"); + wb_send(READ, 16'hC, 32'h0); + `CHECK_VALUE(wb_dat_o, 32'h6, "Verify WB status after PCIe read request"); + wb_send(READ, 16'h4, 32'h0); + `CHECK_VALUE(wb_dat_o, 32'h2000a000, "Verify WB control value after PCIe read request"); + wb_send(READ, 16'hC, 32'h0); + `CHECK_VALUE(wb_dat_o, 32'h4, "Verify WB status value after consuming PCIe read request"); + pcie_send(READ, 20'h6a000, 32'h0); + pcie_recv(RESPONSE, 20'h0, 20'h0); + `CHECK_VALUE(msgo_payload, 32'h1, "Verify PCIe status after WB consumes request only"); + wb_send(WRITE, 16'h0, 32'hDEADBEEF); + wb_send(WRITE, 16'h4, 32'h80000000); + wb_send(READ, 16'hC, 32'h0); + `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after responding to PCIe read request"); + pcie_send(READ, 20'h6a000, 32'h0); + pcie_recv(RESPONSE, 20'h0, 20'h0); + `CHECK_VALUE(msgo_payload, 32'h0, "Verify PCIe status after WB responds to read request"); + pcie_send(READ, 20'h7a000, 32'h0); + pcie_recv(RESPONSE, 20'h0, 20'h0); + `CHECK_VALUE(msgo_payload, 32'hdeadbeef, "Verify PCIe read data"); + + $display("\n[TEST] ZPU Write from PCIe"); + pcie_send(WRITE, 20'h7b000, 32'h12345678); + pcie_send(READ, 20'h7a000, 32'h0); + pcie_recv(RESPONSE, 20'h0, 20'h0); + `CHECK_VALUE(msgo_payload, 32'hdeadbeef, "Verify that PCIe read data is still intact after write"); + wb_send(READ, 16'hC, 32'h0); + `CHECK_VALUE(wb_dat_o, 32'h2, "Verify WB status value after PCIe write request"); + wb_send(READ, 16'h0, 32'h0); + `CHECK_VALUE(wb_dat_o, 32'h12345678, "Verify WB data value after PCIe read request"); + wb_send(READ, 16'h4, 32'h0); + `CHECK_VALUE(wb_dat_o, 32'h4000b000, "Verify WB control value after PCIe read request"); + wb_send(READ, 16'hC, 32'h0); + `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after consuming PCIe write request"); + pcie_send(READ, 20'h6a000, 32'h0); + pcie_recv(RESPONSE, 20'h0, 20'h0); + `CHECK_VALUE(msgo_payload, 32'h0, "Verify PCIe status after WB consumes request"); + + $display("\n[TEST] Chinch Write from ZPU"); + wb_send(READ, 16'hC, 32'h0); + `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value before initiating write request"); + wb_send(WRITE, 16'h0, 32'h00beef00); + wb_send(READ, 16'hC, 32'h0); + `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after writing just the data reg"); + wb_send(WRITE, 16'h4, 32'h40000200); + wb_send(READ, 16'hC, 32'h0); + `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after initiating write"); + pcie_recv(WRITE, 20'h200, 20'h0); + `CHECK_VALUE(msgo_payload, 32'h00beef00, "Verify received PCIe data"); + `CHECK_VALUE(msgo_ctrl, 32'h40000200, "Verify received PCIe control"); + wb_send(WRITE, 16'h0, 32'h00feeb00); + wb_send(WRITE, 16'h4, 32'h400002fc); + pcie_recv(WRITE, 20'h200, 20'h0); + `CHECK_VALUE(msgo_payload, 32'h00feeb00, "Verify second received PCIe data"); + `CHECK_VALUE(msgo_ctrl, 32'h400002fc, "Verify second received PCIe control"); + + $display("\n[TEST] Chinch Read from ZPU"); + wb_send(READ, 16'hC, 32'h0); + `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value before initiating read request"); + wb_send(WRITE, 16'h0, 32'hffffffff); + wb_send(READ, 16'hC, 32'h0); + `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after writing just the data reg"); + wb_send(WRITE, 16'h4, 32'h20000400); + wb_send(READ, 16'hC, 32'h0); + `CHECK_VALUE(wb_dat_o, 32'h1, "Verify WB status value after initiating read request"); + pcie_recv(READ, 20'h400, 20'h0); + `CHECK_VALUE(msgo_payload, 32'hffffffff, "Verify received PCIe data"); + `CHECK_VALUE(msgo_ctrl, 32'h20000400, "Verify received PCIe control"); + wb_send(READ, 16'hC, 32'h0); + wb_send(READ, 16'hC, 32'h0); + `CHECK_VALUE(wb_dat_o, 32'h1, "Verify WB status value before PCIe responds"); + pcie_send(RESPONSE, 20'h000, 32'hace06666); + wb_send(READ, 16'hC, 32'h0); + `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after PCIe responds"); + wb_send(READ, 16'h8, 32'h0); + `CHECK_VALUE(wb_dat_o, 32'hace06666, "Verify WB read value after PCIe responds"); + + $display("\n[TEST] WB Outbound flood"); + wb_send(READ, 16'hC, 32'h0); + `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status before request flood"); + for (it = 0; it < 64; it = it + 1) begin + wb_send(WRITE, 16'h4, 32'h20000400); + end + wb_send(READ, 16'hC, 32'h0); + `CHECK_VALUE(wb_dat_o, 32'h11, "Verify WB status after request flood"); + for (it = 0; it < 64; it = it + 1) begin + pcie_recv(READ, 20'h400, 20'h0); + end + wb_send(READ, 16'hC, 32'h0); + `CHECK_VALUE(wb_dat_o, 32'h1, "Verify WB status after consuming requests"); + + $display("\n[TEST] PCIe Transaction Status"); + pcie_send(READ, 20'h6a000, 32'h0); + pcie_recv(RESPONSE, 20'h0, 20'h0); + `CHECK_VALUE(msgo_payload, 32'h0, "Verify PCIe status before multiple reads"); + pcie_send(WRITE, 20'h6a000, 32'h0); + pcie_send(WRITE, 20'h6a000, 32'h0); + pcie_send(WRITE, 20'h6a000, 32'h0); + pcie_send(READ, 20'h6a000, 32'h0); + pcie_recv(RESPONSE, 20'h0, 20'h0); + pcie_send(READ, 20'h6a000, 32'h0); + pcie_recv(RESPONSE, 20'h0, 20'h0); + pcie_send(READ, 20'h6a000, 32'h0); + pcie_recv(RESPONSE, 20'h0, 20'h0); + `CHECK_VALUE(msgo_payload, 32'h1, "Verify PCIe status before multiple read requests and status queries"); + wb_send(READ, 16'h4, 32'h0); + wb_send(WRITE, 16'h0, 32'hDEADBEEF); + wb_send(WRITE, 16'h4, 32'h80000000); + pcie_send(READ, 20'h6a000, 32'h0); + pcie_recv(RESPONSE, 20'h0, 20'h0); + `CHECK_VALUE(msgo_payload, 32'h0, "Verify PCIe status after response"); + + $display("\n[DONE]"); + + + end // initial begin + + pcie_wb_reg_core #(.WB_ADDRW(16), .WB_DATAW(32)) dut ( + .clk(clk), .rst(reset), + .wb_stb_i(wb_stb_i), .wb_we_i(wb_we_i), .wb_adr_i(wb_adr_i), + .wb_dat_i(wb_dat_i), .wb_ack_o(wb_ack_o), .wb_dat_o(wb_dat_o), + .msgi_tdata(msgi_data), .msgi_tvalid(msgi_valid), .msgi_tready(msgi_ready), + .msgo_tdata(msgo_data), .msgo_tvalid(msgo_valid), .msgo_tready(msgo_ready), + .debug()); + + +endmodule |