aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/sim/io_port2
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/lib/sim/io_port2')
-rw-r--r--fpga/usrp3/lib/sim/io_port2/pcie_dma_ctrl/pcie_dma_ctrl_tb.v92
-rw-r--r--fpga/usrp3/lib/sim/io_port2/pcie_iop2_msg_arbiter/pcie_iop2_msg_arbiter_tb.v110
-rw-r--r--fpga/usrp3/lib/sim/io_port2/pcie_wb_reg_core/pcie_wb_reg_core_tb.v243
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