diff options
author | Ben Hilburn <ben.hilburn@ettus.com> | 2014-02-14 12:05:07 -0800 |
---|---|---|
committer | Ben Hilburn <ben.hilburn@ettus.com> | 2014-02-14 12:05:07 -0800 |
commit | ff1546f8137f7f92bb250f685561b0c34cc0e053 (patch) | |
tree | 7fa6fd05c8828df256a1b20e2935bd3ba9899e2c /fpga/usrp3/lib/axi/axi_chdr_test_pattern.v | |
parent | 4f691d88123784c2b405816925f1a1aef69d18c1 (diff) | |
download | uhd-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.v | 314 |
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 + + + |