aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/axi/axi_chdr_test_pattern.v
diff options
context:
space:
mode:
authorBen Hilburn <ben.hilburn@ettus.com>2014-02-14 12:05:07 -0800
committerBen Hilburn <ben.hilburn@ettus.com>2014-02-14 12:05:07 -0800
commitff1546f8137f7f92bb250f685561b0c34cc0e053 (patch)
tree7fa6fd05c8828df256a1b20e2935bd3ba9899e2c /fpga/usrp3/lib/axi/axi_chdr_test_pattern.v
parent4f691d88123784c2b405816925f1a1aef69d18c1 (diff)
downloaduhd-ff1546f8137f7f92bb250f685561b0c34cc0e053.tar.gz
uhd-ff1546f8137f7f92bb250f685561b0c34cc0e053.tar.bz2
uhd-ff1546f8137f7f92bb250f685561b0c34cc0e053.zip
Pushing the bulk of UHD-3.7.0 code.
Diffstat (limited to 'fpga/usrp3/lib/axi/axi_chdr_test_pattern.v')
-rw-r--r--fpga/usrp3/lib/axi/axi_chdr_test_pattern.v314
1 files changed, 314 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/axi/axi_chdr_test_pattern.v b/fpga/usrp3/lib/axi/axi_chdr_test_pattern.v
new file mode 100644
index 000000000..7d25f3008
--- /dev/null
+++ b/fpga/usrp3/lib/axi/axi_chdr_test_pattern.v
@@ -0,0 +1,314 @@
+//
+// Synthesizable test pattern generators and checkers
+// for CHDR that can be used to test transparent blocks
+// (FIFOs, switches, etc)
+//
+
+//`define MTU 8192
+`define MTU 1536
+
+module axi_chdr_test_pattern
+ (
+ input clk,
+ input reset,
+
+ //
+ // CHDR friendly AXI stream input
+ //
+ output reg [63:0] i_tdata,
+ output reg i_tlast,
+ output reg i_tvalid,
+ input wire i_tready,
+ //
+ // CHDR friendly AXI Stream output
+ //
+ input wire [63:0] o_tdata,
+ input wire o_tlast,
+ input wire o_tvalid,
+ output reg o_tready,
+ //
+ // Test flags
+ //
+ input start,
+ input [15:0] control,
+ output reg fail,
+ output reg done
+ );
+
+ wire [7:0] bist_rx_delay = control[7:0];
+ wire [7:0] bist_tx_delay = control[15:8];
+
+
+ reg [15:0] tx_count, rx_count;
+ reg [15:0] tx_data, rx_data;
+ reg [7:0] tx_delay, rx_delay;
+
+
+ localparam TX_IDLE = 0;
+ localparam TX_START = 1;
+ localparam TX_ACTIVE = 2;
+ localparam TX_GAP = 3;
+ localparam TX_DONE = 4;
+ localparam TX_WAIT = 5;
+
+ localparam RX_IDLE = 0;
+ localparam RX_ACTIVE = 1;
+ localparam RX_FAIL = 2;
+ localparam RX_DONE = 3;
+ localparam RX_WAIT = 4;
+
+ reg [2:0] tx_state, rx_state;
+
+ //
+ // Transmitter
+ //
+ always @(posedge clk)
+ if (reset)
+ begin
+ tx_delay <= 0;
+ tx_count <= 8;
+ tx_data <= 0;
+ i_tdata <= 64'h0;
+ i_tlast <= 1'b0;
+ i_tvalid <= 1'b0;
+ tx_state <= TX_IDLE;
+ end
+ else
+ begin
+ case(tx_state)
+ TX_IDLE: begin
+ tx_delay <= 0;
+ i_tdata <= 64'h0;
+ i_tlast <= 1'b0;
+ i_tvalid <= 1'b0;
+ tx_data <= 0;
+ tx_count <= 4;
+ // Run whilst start asserted.
+ if (start) begin
+ tx_state <= TX_START;
+ // ....Go back to initialized state if start deasserted.
+ end else begin
+ tx_state <= TX_IDLE;
+ end
+ end // case: TX_IDLE
+
+ //
+ // START signal is asserted.
+ // Now need to start transmiting a packet.
+ //
+ TX_START: begin
+ // At the next clock edge drive first beat of new packet onto HDR bus.
+ i_tlast <= 1'b0;
+ i_tvalid <= 1'b1;
+ tx_data <= tx_data + 4;
+ // i_tdata <= {tx_data,tx_data+16'd1,tx_data+16'd2,tx_data+16'd3};
+ i_tdata <= {4{(tx_data[2]?16'hffff:16'h0000)^tx_data[15:0]}};
+ tx_state <= TX_ACTIVE;
+
+ end
+
+ //
+ // Valid data is (already) being driven onto the CHDR bus.
+ // i_tlast may also be driven asserted if current data count has reached EOP.
+ // Watch i_tready to see when it's consumed.
+ // When packets are consumed increment data counter or transition state if
+ // EOP has sucsesfully concluded.
+ //
+ TX_ACTIVE: begin
+ i_tvalid <= 1'b1; // Always assert tvalid
+ if (i_tready) begin
+
+// i_tdata <= {tx_data,tx_data+16'd1,tx_data+16'd2,tx_data+16'd3};
+ i_tdata <= {4{(tx_data[2]?16'hffff:16'h0000)^tx_data[15:0]}};
+ // Will this next beat be the last in a packet?
+ if (tx_data == tx_count) begin
+ tx_data <= 0;
+ i_tlast <= 1'b1;
+ tx_state <= TX_GAP;
+ end else begin
+ tx_data <= tx_data + 4;
+ i_tlast <= 1'b0;
+ tx_state <= TX_ACTIVE;
+ end
+ end else begin
+ // Keep driving all CHDR bus signals as-is until i_tready is asserted.
+ tx_state <= TX_ACTIVE;
+ end
+ end // case: TX_ACTIVE
+ //
+ // Force an inter-packet gap between packets in a BIST sequence where tvalid is driven low.
+ // As we leave this state check if all packets in BIST sequence have been generated yet,
+ // and if so go to done state.
+ //
+ TX_GAP: begin
+ if (i_tready) begin
+ i_tvalid <= 1'b0;
+ i_tdata <= 64'h0;
+ i_tlast <= 1'b0;
+ tx_count <= tx_count + 4;
+
+ if (tx_count < `MTU) begin
+ tx_state <= TX_WAIT;
+ tx_delay <= bist_tx_delay;
+ end else
+ tx_state <= TX_DONE;
+ end else begin // if (i_tready)
+ tx_state <= TX_GAP;
+ end
+ end // case: TX_GAP
+ //
+ // Simulate inter packet gap in real UHD system
+ TX_WAIT: begin
+ if (tx_delay == 0)
+ tx_state <= TX_START;
+ else begin
+ tx_delay <= tx_delay - 1;
+ tx_state <= TX_WAIT;
+ end
+ end
+
+ //
+ // Complete test pattern BIST sequence has been transmitted. Sit in this
+ // state indefinately if START is taken low, which re-inits the whole BIST solution.
+ //
+ TX_DONE: begin
+ if (!start) begin
+ tx_state <= TX_DONE;
+ end else begin
+ tx_state <= TX_IDLE;
+ end
+ i_tvalid <= 1'b0;
+ i_tdata <= 64'd0;
+ i_tlast <= 1'b0;
+
+ end
+ endcase // case (tx_state)
+ end
+
+ //
+ // Receiver
+ //
+ always @(posedge clk)
+ if (reset)
+ begin
+ rx_delay <= 0;
+ rx_count <= 0;
+ rx_data <= 0;
+ o_tready <= 1'b0;
+ rx_state <= RX_IDLE;
+ fail <= 1'b0;
+ done <= 1'b0;
+
+ end
+ else begin
+ case (rx_state)
+ RX_IDLE: begin
+ rx_delay <= 0;
+ o_tready <= 1'b0;
+ rx_data <= 0;
+ rx_count <= 4;
+ fail <= 1'b0;
+ done <= 1'b0;
+ // Not accepting data whilst Idle,
+ // switch to active when packet arrives
+ if (o_tvalid) begin
+ o_tready <= 1'b1;
+ rx_state <= RX_ACTIVE;
+ end else
+ rx_state <= RX_IDLE;
+ end
+
+ RX_ACTIVE: begin
+ o_tready <= 1'b1;
+ if (o_tvalid)
+// if (o_tdata != {rx_data,rx_data+16'd1,rx_data+16'd2,rx_data+16'd3})
+ if (o_tdata != {4{(rx_data[2]?16'hffff:16'h0000)^rx_data[15:0]}})
+ begin
+ $display("o_tdata: %x != expected: %x @ time: %d",o_tdata,
+// {rx_data,rx_data+16'd1,rx_data+16'd2,rx_data+16'd3},
+ {4{(rx_data[2]?16'hffff:16'h0000)^rx_data[15:0]}},
+ $time);
+ rx_state <= RX_FAIL;
+ end
+ else
+ // Should last be asserted?
+ if (rx_data == rx_count)
+ // ...last not asserted when it should be!
+ if (~(o_tlast===1)) begin
+ $display("o_tlast not asserted when it should be @ time: %d",$time);
+ rx_state <= RX_FAIL;
+ end else begin
+ // End of packet, set up to RX next
+ rx_data <= 0;
+ rx_count <= rx_count + 4;
+ rx_delay <= bist_rx_delay;
+ if (rx_count == `MTU) begin
+ rx_state <= RX_DONE;
+ end else begin
+ rx_state <= RX_WAIT;
+ end
+ o_tready <= 1'b0;
+ end
+ else
+ // ...last asserted when it should not be!
+ if (~(o_tlast===0)) begin
+ $display("o_tlast asserted when it should not be @ time: %d",$time);
+ rx_state <= RX_FAIL;
+ end else begin
+ // Still in packet body
+ rx_data <= rx_data + 4;
+ rx_delay <= bist_rx_delay;
+ rx_state <= RX_WAIT;
+ o_tready <= 1'b0;
+ end
+ else
+ // Nothing to do this cycle
+ rx_state <= RX_ACTIVE;
+ end // case: RX_ACTIVE
+
+ // To simulate the radio consuming samples at a steady rate set by the decimation
+ // have a programable delay here
+ RX_WAIT: begin
+ if (rx_delay == 0) begin
+ rx_state <= RX_ACTIVE;
+ o_tready <= 1'b1;
+ end else begin
+ rx_delay <= rx_delay - 1;
+ rx_state <= RX_WAIT;
+ end
+ end
+
+
+ RX_FAIL: begin
+ o_tready <= 1'b0;
+ done <= 1'b1;
+ fail <= 1'b1;
+ // If start is deasserted allow BIST logic to reset and rearm
+ if (start)
+ rx_state <= RX_FAIL;
+ else
+ rx_state <= RX_IDLE;
+
+ end
+
+ RX_DONE: begin
+ o_tready <= 1'b0;
+ done <= 1'b1;
+ fail <= 1'b0;
+ // If start is asserted allow BIST logic to reset, rearm & restart
+ if (!start)
+ rx_state <= RX_DONE;
+ else
+ rx_state <= RX_IDLE;
+
+ end
+
+ endcase // case (rx_state)
+ end
+
+
+
+endmodule
+
+
+