//====================================================================== // // coretest.v // ---------- // The Cryptech coretest testing module. Combined with an external // interface that sends and receives bytes using a SYN-ACK // handshake and a core to be tested, coretest can parse read // and write commands needed to test the connected core. // // // Author: Joachim Strombergson // Copyright (c) 2014, SUNET // // Redistribution and use in source and binary forms, with or // without modification, are permitted provided that the following // conditions are met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in // the documentation and/or other materials provided with the // distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // //====================================================================== module coretest( input wire clk, input wire reset_n, // Interface to communication core input wire rx_syn, input wire [7 : 0] rx_data, output wire rx_ack, output wire tx_syn, output wire [7 : 0] tx_data, input wire tx_ack, // Interface to the core being tested. output wire core_reset_n, output wire core_cs, output wire core_we, output wire [15 : 0] core_address, output wire [31 : 0] core_write_data, input wire [31 : 0] core_read_data, input wire core_error ); //---------------------------------------------------------------- // Internal constant and parameter definitions. //---------------------------------------------------------------- // Max elements in read and write buffers. parameter BUFFER_MAX = 4'hf; // Command constants. parameter SOC = 8'h55; parameter EOC = 8'haa; parameter RESET_CMD = 8'h01; parameter READ_CMD = 8'h10; parameter WRITE_CMD = 8'h11; // Response constants. parameter SOR = 8'haa; parameter EOR = 8'h55; parameter UNKNOWN = 8'hfe; parameter ERROR = 8'hfd; parameter READ_OK = 8'h7f; parameter WRITE_OK = 8'h7e; parameter RESET_OK = 8'h7d; // rx_engine states. parameter RX_IDLE = 3'h0; parameter RX_ACK = 3'h1; parameter RX_NSYN = 3'h2; // tx_engine states. parameter TX_IDLE = 3'h0; parameter TX_SYN = 3'h1; parameter TX_NOACK = 3'h2; parameter TX_NEXT = 3'h3; parameter TX_SENT = 3'h4; parameter TX_DONE = 3'h5; // test_engine states. parameter TEST_IDLE = 8'h00; parameter TEST_GET_CMD = 8'h10; parameter TEST_PARSE_CMD = 8'h11; parameter TEST_GET_ADDR0 = 8'h20; parameter TEST_GET_ADDR1 = 8'h21; parameter TEST_GET_DATA0 = 8'h24; parameter TEST_GET_DATA1 = 8'h25; parameter TEST_GET_DATA2 = 8'h26; parameter TEST_GET_DATA3 = 8'h27; parameter TEST_GET_EOC = 8'h28; parameter TEST_RST_START = 8'h30; parameter TEST_RST_WAIT = 8'h31; parameter TEST_RST_END = 8'h32; parameter TEST_RD_START = 8'h50; parameter TEST_RD_WAIT = 8'h51; parameter TEST_RD_END = 8'h52; parameter TEST_WR_START = 8'h60; parameter TEST_WR_WAIT = 8'h61; parameter TEST_WR_END = 8'h62; parameter TEST_CMD_UNKNOWN = 8'h80; parameter TEST_CMD_ERROR = 8'h81; parameter TEST_SEND_RESPONSE = 8'hc0; //---------------------------------------------------------------- // Registers including update variables and write enable. //---------------------------------------------------------------- reg rx_syn_reg; reg rx_ack_reg; reg rx_ack_new; reg rx_ack_we; reg tx_syn_reg; reg tx_syn_new; reg tx_syn_we; reg tx_ack_reg; reg core_reset_n_reg; reg core_reset_n_new; reg core_reset_n_we; reg core_cs_reg; reg core_cs_new; reg core_cs_we; reg core_we_reg; reg core_we_new; reg core_we_we; reg send_response_reg; reg send_response_new; reg send_response_we; reg response_sent_reg; reg response_sent_new; reg response_sent_we; reg [7 : 0] cmd_reg; reg [7 : 0] cmd_we; reg [7 : 0] core_addr_byte0_reg; reg core_addr_byte0_we; reg [7 : 0] core_addr_byte1_reg; reg core_addr_byte1_we; reg [7 : 0] core_wr_data_byte0_reg; reg core_wr_data_byte0_we; reg [7 : 0] core_wr_data_byte1_reg; reg core_wr_data_byte1_we; reg [7 : 0] core_wr_data_byte2_reg; reg core_wr_data_byte2_we; reg [7 : 0] core_wr_data_byte3_reg; reg core_wr_data_byte3_we; reg [31 : 0] core_read_data_reg; reg core_error_reg; reg sample_core_output; reg [3 : 0] rx_buffer_rd_ptr_reg; reg [3 : 0] rx_buffer_rd_ptr_new; reg rx_buffer_rd_ptr_we; reg rx_buffer_rd_ptr_inc; reg [3 : 0] rx_buffer_wr_ptr_reg; reg [3 : 0] rx_buffer_wr_ptr_new; reg rx_buffer_wr_ptr_we; reg rx_buffer_wr_ptr_inc; reg [3 : 0] rx_buffer_ctr_reg; reg [3 : 0] rx_buffer_ctr_new; reg rx_buffer_ctr_we; reg rx_buffer_ctr_inc; reg rx_buffer_ctr_dec; reg rx_buffer_full; reg rx_buffer_empty; reg [7 : 0] rx_buffer [0 : 15]; reg rx_buffer_we; reg [3 : 0] tx_buffer_ptr_reg; reg [3 : 0] tx_buffer_ptr_new; reg tx_buffer_ptr_we; reg tx_buffer_ptr_inc; reg tx_buffer_ptr_rst; reg [7 : 0] tx_buffer [0 : 8]; reg tx_buffer_we; reg [3 : 0] tx_msg_len_reg; reg [3 : 0] tx_msg_len_new; reg tx_msg_len_we; reg [2 : 0] rx_engine_reg; reg [2 : 0] rx_engine_new; reg rx_engine_we; reg [2 : 0] tx_engine_reg; reg [2 : 0] tx_engine_new; reg tx_engine_we; reg [7 : 0] test_engine_reg; reg [7 : 0] test_engine_new; reg test_engine_we; //---------------------------------------------------------------- // Wires. //---------------------------------------------------------------- reg [7 : 0] tx_buffer_muxed0; reg [7 : 0] tx_buffer_muxed1; reg [7 : 0] tx_buffer_muxed2; reg [7 : 0] tx_buffer_muxed3; reg [7 : 0] tx_buffer_muxed4; reg [7 : 0] tx_buffer_muxed5; reg [7 : 0] tx_buffer_muxed6; reg [7 : 0] tx_buffer_muxed7; reg [7 : 0] tx_buffer_muxed8; reg update_tx_buffer; reg [7 : 0] response_type; reg [7 : 0] rx_byte; //---------------------------------------------------------------- // Concurrent connectivity for ports etc. //---------------------------------------------------------------- assign rx_ack = rx_ack_reg; assign tx_syn = tx_syn_reg; assign tx_data = tx_buffer[tx_buffer_ptr_reg]; assign core_reset_n = core_reset_n_reg & reset_n; assign core_cs = core_cs_reg; assign core_we = core_we_reg; assign core_address = {core_addr_byte0_reg, core_addr_byte1_reg}; assign core_write_data = {core_wr_data_byte0_reg, core_wr_data_byte1_reg, core_wr_data_byte2_reg, core_wr_data_byte3_reg}; //---------------------------------------------------------------- // reg_update // Update functionality for all registers in the core. // All registers are positive edge triggered with synchronous // active low reset. All registers have write enable. //---------------------------------------------------------------- always @ (posedge clk) begin: reg_update if (!reset_n) begin rx_buffer[0] <= 8'h00; rx_buffer[1] <= 8'h00; rx_buffer[2] <= 8'h00; rx_buffer[3] <= 8'h00; rx_buffer[4] <= 8'h00; rx_buffer[5] <= 8'h00; rx_buffer[6] <= 8'h00; rx_buffer[7] <= 8'h00; rx_buffer[8] <= 8'h00; rx_buffer[9] <= 8'h00; rx_buffer[10] <= 8'h00; rx_buffer[11] <= 8'h00; rx_buffer[12] <= 8'h00; rx_buffer[13] <= 8'h00; rx_buffer[14] <= 8'h00; rx_buffer[15] <= 8'h00; tx_buffer[0] <= 8'h00; tx_buffer[1] <= 8'h00; tx_buffer[2] <= 8'h00; tx_buffer[3] <= 8'h00; tx_buffer[4] <= 8'h00; tx_buffer[5] <= 8'h00; tx_buffer[6] <= 8'h00; tx_buffer[7] <= 8'h00; tx_buffer[8] <= 8'h00; rx_syn_reg <= 0; rx_ack_reg <= 0; tx_ack_reg <= 0; tx_syn_reg <= 0; rx_buffer_rd_ptr_reg <= 4'h0; rx_buffer_wr_ptr_reg <= 4'h0; rx_buffer_ctr_reg <= 4'h0; tx_buffer_ptr_reg <= 4'h0; tx_msg_len_reg <= 4'h0; send_response_reg <= 0; response_sent_reg <= 0; cmd_reg <= 8'h00; core_addr_byte0_reg <= 8'h00; core_addr_byte1_reg <= 8'h00; core_wr_data_byte0_reg <= 8'h00; core_wr_data_byte1_reg <= 8'h00; core_wr_data_byte2_reg <= 8'h00; core_wr_data_byte3_reg <= 8'h00; core_reset_n_reg <= 1; core_cs_reg <= 0; core_we_reg <= 0; core_error_reg <= 0; core_read_data_reg <= 32'h00000000; rx_engine_reg <= RX_IDLE; tx_engine_reg <= TX_IDLE; test_engine_reg <= TEST_IDLE; end else begin rx_syn_reg <= rx_syn; tx_ack_reg <= tx_ack; if (rx_ack_we) begin rx_ack_reg <= rx_ack_new; end if (tx_syn_we) begin tx_syn_reg <= tx_syn_new; end if (rx_buffer_we) begin rx_buffer[rx_buffer_wr_ptr_reg] <= rx_data; end if (tx_buffer_we) begin tx_buffer[0] <= tx_buffer_muxed0; tx_buffer[1] <= tx_buffer_muxed1; tx_buffer[2] <= tx_buffer_muxed2; tx_buffer[3] <= tx_buffer_muxed3; tx_buffer[4] <= tx_buffer_muxed4; tx_buffer[5] <= tx_buffer_muxed5; tx_buffer[6] <= tx_buffer_muxed6; tx_buffer[7] <= tx_buffer_muxed7; tx_buffer[8] <= tx_buffer_muxed8; end if (cmd_we) begin cmd_reg <= rx_byte; end if (core_addr_byte0_we) begin core_addr_byte0_reg <= rx_byte; end if (core_addr_byte1_we) begin core_addr_byte1_reg <= rx_byte; end if (core_wr_data_byte0_we) begin core_wr_data_byte0_reg <= rx_byte; end if (core_wr_data_byte1_we) begin core_wr_data_byte1_reg <= rx_byte; end if (core_wr_data_byte2_we) begin core_wr_data_byte2_reg <= rx_byte; end if (core_wr_data_byte3_we) begin core_wr_data_byte3_reg <= rx_byte; end if (rx_buffer_rd_ptr_we) begin rx_buffer_rd_ptr_reg <= rx_buffer_rd_ptr_new; end if (rx_buffer_wr_ptr_we) begin rx_buffer_wr_ptr_reg <= rx_buffer_wr_ptr_new; end if (rx_buffer_ctr_we) begin rx_buffer_ctr_reg <= rx_buffer_ctr_new; end if (tx_buffer_ptr_we) begin tx_buffer_ptr_reg <= tx_buffer_ptr_new; end if (tx_msg_len_we) begin tx_msg_len_reg <= tx_msg_len_new; end if (core_reset_n_we) begin core_reset_n_reg <= core_reset_n_new; end if (core_cs_we) begin core_cs_reg <= core_cs_new; end if (core_we_we) begin core_we_reg <= core_we_new; end if (send_response_we) begin send_response_reg <= send_response_new; end if (response_sent_we) begin response_sent_reg <= response_sent_new; end if (sample_core_output) begin core_error_reg <= core_error; core_read_data_reg <= core_read_data; end if (rx_engine_we) begin rx_engine_reg <= rx_engine_new; end if (tx_engine_we) begin tx_engine_reg <= tx_engine_new; end if (test_engine_we) begin test_engine_reg <= test_engine_new; end end end // reg_update //--------------------------------------------------------------- // read_rx_buffer // Combinatinal read mux for the rx_buffer. //--------------------------------------------------------------- always @* begin : read_rx_buffer rx_byte = rx_buffer[rx_buffer_rd_ptr_reg]; end // read_rx_buffer //--------------------------------------------------------------- // tx_buffer_logic // // Update logic for the tx-buffer. Given the response type and // the correct contents of the tx_buffer is assembled when // and update is signalled by the test engine. //--------------------------------------------------------------- always @* begin: tx_buffer_logic // Defafult assignments tx_buffer_muxed0 = 8'h00; tx_buffer_muxed1 = 8'h00; tx_buffer_muxed2 = 8'h00; tx_buffer_muxed3 = 8'h00; tx_buffer_muxed4 = 8'h00; tx_buffer_muxed5 = 8'h00; tx_buffer_muxed6 = 8'h00; tx_buffer_muxed7 = 8'h00; tx_buffer_muxed8 = 8'h00; tx_msg_len_new = 4'h0; tx_msg_len_we = 0; tx_buffer_we = 0; if (update_tx_buffer) begin tx_buffer_we = 1; tx_buffer_muxed0 = SOR; case (response_type) READ_OK: begin tx_buffer_muxed1 = READ_OK; tx_buffer_muxed2 = core_addr_byte0_reg; tx_buffer_muxed3 = core_addr_byte1_reg; tx_buffer_muxed4 = core_read_data_reg[31 : 24]; tx_buffer_muxed5 = core_read_data_reg[23 : 16]; tx_buffer_muxed6 = core_read_data_reg[15 : 8]; tx_buffer_muxed7 = core_read_data_reg[7 : 0]; tx_buffer_muxed8 = EOR; tx_msg_len_new = 4'h8; tx_msg_len_we = 1; end WRITE_OK: begin tx_buffer_muxed1 = WRITE_OK; tx_buffer_muxed2 = core_addr_byte0_reg; tx_buffer_muxed3 = core_addr_byte1_reg; tx_buffer_muxed4 = EOR; tx_msg_len_new = 4'h4; tx_msg_len_we = 1; end RESET_OK: begin tx_buffer_muxed1 = RESET_OK; tx_buffer_muxed2 = EOR; tx_msg_len_new = 4'h2; tx_msg_len_we = 1; end ERROR: begin tx_buffer_muxed1 = ERROR; tx_buffer_muxed2 = cmd_reg; tx_buffer_muxed3 = EOR; tx_msg_len_new = 4'h3; tx_msg_len_we = 1; end default: begin // Any response type not explicitly defined is treated as UNKNOWN. tx_buffer_muxed1 = UNKNOWN; tx_buffer_muxed2 = cmd_reg; tx_buffer_muxed3 = EOR; tx_msg_len_new = 4'h3; tx_msg_len_we = 1; end endcase // case (response_type) end end // tx_buffer_logic //---------------------------------------------------------------- // rx_buffer_rd_ptr // // Logic for the rx buffer read pointer. //---------------------------------------------------------------- always @* begin: rx_buffer_rd_ptr // Default assignments rx_buffer_rd_ptr_new = 4'h0; rx_buffer_rd_ptr_we = 1'b0; rx_buffer_ctr_dec = 0; if (rx_buffer_rd_ptr_inc) begin rx_buffer_ctr_dec = 1; rx_buffer_rd_ptr_new = rx_buffer_rd_ptr_reg + 1'b1; rx_buffer_rd_ptr_we = 1'b1; end end // rx_buffer_rd_ptr //---------------------------------------------------------------- // rx_buffer_wr_ptr // // Logic for the rx buffer write pointer. //---------------------------------------------------------------- always @* begin: rx_buffer_wr_ptr // Default assignments rx_buffer_wr_ptr_new = 4'h0; rx_buffer_wr_ptr_we = 1'b0; rx_buffer_ctr_inc = 0; if (rx_buffer_wr_ptr_inc) begin rx_buffer_ctr_inc = 1; rx_buffer_wr_ptr_new = rx_buffer_wr_ptr_reg + 1'b1; rx_buffer_wr_ptr_we = 1'b1; end end // rx_buffer_wr_ptr //---------------------------------------------------------------- // rx_buffer_ctr // // Logic for the rx buffer element counter. //---------------------------------------------------------------- always @* begin: rx_buffer_ctr // Default assignments rx_buffer_ctr_new = 4'h0; rx_buffer_ctr_we = 1'b0; rx_buffer_empty = 1'b0; rx_buffer_full = 1'b0; if (rx_buffer_ctr_inc) begin rx_buffer_ctr_new = rx_buffer_ctr_reg + 1'b1; rx_buffer_ctr_we = 1'b1; end else if (rx_buffer_ctr_dec) begin rx_buffer_ctr_new = rx_buffer_ctr_reg - 1'b1; rx_buffer_ctr_we = 1'b1; end if (rx_buffer_ctr_reg == 4'h0) begin rx_buffer_empty = 1'b1; end if (rx_buffer_ctr_reg == BUFFER_MAX) begin rx_buffer_full = 1'b1; end end // rx_buffer_ctr //---------------------------------------------------------------- // tx_buffer_ptr // // Logic for the tx buffer pointer. Supports reset and // incremental updates. //---------------------------------------------------------------- always @* begin: tx_buffer_ptr // Default assignments tx_buffer_ptr_new = 4'h0; tx_buffer_ptr_we = 1'b0; if (tx_buffer_ptr_inc) begin tx_buffer_ptr_new = tx_buffer_ptr_reg + 1'b1; tx_buffer_ptr_we = 1'b1; end else if (tx_buffer_ptr_rst) begin tx_buffer_ptr_new = 4'h0; tx_buffer_ptr_we = 1'b1; end end // tx_buffer_ptr //---------------------------------------------------------------- // rx_engine // // FSM responsible for handling receiving message bytes from the // host interface and storing them in the receive buffer. //---------------------------------------------------------------- always @* begin: rx_engine // Default assignments rx_ack_new = 1'b0; rx_ack_we = 1'b0; rx_buffer_we = 1'b0; rx_buffer_wr_ptr_inc = 1'b0; rx_engine_new = RX_IDLE; rx_engine_we = 1'b0; case (rx_engine_reg) RX_IDLE: begin if (rx_syn_reg) begin if (!rx_buffer_full) begin rx_buffer_we = 1'b1; rx_engine_new = RX_ACK; rx_engine_we = 1'b1; end end end RX_ACK: begin rx_ack_new = 1'b1; rx_ack_we = 1'b1; rx_buffer_wr_ptr_inc = 1'b1; rx_engine_new = RX_NSYN; rx_engine_we = 1'b1; end RX_NSYN: begin if (!rx_syn_reg) begin rx_ack_new = 1'b0; rx_ack_we = 1'b1; rx_engine_new = RX_IDLE; rx_engine_we = 1; end end default: begin end endcase // case (rx_engine_reg) end // rx_engine //---------------------------------------------------------------- // tx_engine // // FSM responsible for handling transmitting message bytes // to the host interface. //---------------------------------------------------------------- always @* begin: tx_engine // Default assignments tx_buffer_ptr_inc = 0; tx_buffer_ptr_rst = 0; response_sent_new = 0; response_sent_we = 0; tx_syn_new = 0; tx_syn_we = 0; tx_engine_new = TX_IDLE; tx_engine_we = 0; case (tx_engine_reg) TX_IDLE: begin if (send_response_reg) begin tx_syn_new = 1; tx_syn_we = 1; tx_engine_new = TX_SYN; tx_engine_we = 1; end end TX_SYN: begin if (tx_ack_reg) begin tx_syn_new = 0; tx_syn_we = 1; tx_engine_new = TX_NOACK; tx_engine_we = 1; end end TX_NOACK: begin if (!tx_ack_reg) begin tx_engine_new = TX_NEXT; tx_engine_we = 1; end end TX_NEXT: begin if (tx_buffer_ptr_reg == tx_msg_len_reg) begin tx_engine_new = TX_SENT; tx_engine_we = 1; end else begin tx_buffer_ptr_inc = 1; tx_syn_new = 1; tx_syn_we = 1; tx_engine_new = TX_SYN; tx_engine_we = 1; end end TX_SENT: begin response_sent_new = 1; response_sent_we = 1; tx_engine_new = TX_DONE; tx_engine_we = 1; end TX_DONE: begin response_sent_new = 0; response_sent_we = 1; tx_buffer_ptr_rst = 1; tx_engine_new = TX_IDLE; tx_engine_we = 1; end default: begin tx_engine_new = TX_IDLE; tx_engine_we = 1; end endcase // case (tx_engine_reg) end // tx_engine //---------------------------------------------------------------- // test_engine // // Test engine FSM logic. Parses received commands, tries to // execute the commands and assmbles the response to the // given commands. //---------------------------------------------------------------- always @* begin: test_engine // Default assignments. core_reset_n_new = 1; core_reset_n_we = 0; core_cs_new = 0; core_cs_we = 0; core_we_new = 0; core_we_we = 0; sample_core_output = 0; update_tx_buffer = 0; response_type = 8'h00; rx_buffer_rd_ptr_inc = 0; cmd_we = 0; core_addr_byte0_we = 0; core_addr_byte1_we = 0; core_wr_data_byte0_we = 0; core_wr_data_byte1_we = 0; core_wr_data_byte2_we = 0; core_wr_data_byte3_we = 0; send_response_new = 0; send_response_we = 0; test_engine_new = TEST_IDLE; test_engine_we = 0; case (test_engine_reg) TEST_IDLE: begin if (!rx_buffer_empty) begin rx_buffer_rd_ptr_inc = 1; if (rx_byte == SOC) begin test_engine_new = TEST_GET_CMD; test_engine_we = 1; end end end TEST_GET_CMD: begin if (!rx_buffer_empty) begin rx_buffer_rd_ptr_inc = 1; cmd_we = 1; test_engine_new = TEST_PARSE_CMD; test_engine_we = 1; end end TEST_PARSE_CMD: begin case (cmd_reg) RESET_CMD: begin test_engine_new = TEST_GET_EOC; test_engine_we = 1; end READ_CMD: begin test_engine_new = TEST_GET_ADDR0; test_engine_we = 1; end WRITE_CMD: begin test_engine_new = TEST_GET_ADDR0; test_engine_we = 1; end default: begin test_engine_new = TEST_CMD_UNKNOWN; test_engine_we = 1; end endcase // case (cmd_reg) end TEST_GET_ADDR0: begin if (!rx_buffer_empty) begin rx_buffer_rd_ptr_inc = 1; core_addr_byte0_we = 1; test_engine_new = TEST_GET_ADDR1; test_engine_we = 1; end end TEST_GET_ADDR1: begin if (!rx_buffer_empty) begin rx_buffer_rd_ptr_inc = 1; core_addr_byte1_we = 1; case (cmd_reg) READ_CMD: begin test_engine_new = TEST_GET_EOC; test_engine_we = 1; end WRITE_CMD: begin test_engine_new = TEST_GET_DATA0; test_engine_we = 1; end default: begin test_engine_new = TEST_CMD_UNKNOWN; test_engine_we = 1; end endcase // case (cmd_reg) end end TEST_GET_DATA0: begin if (!rx_buffer_empty) begin rx_buffer_rd_ptr_inc = 1; core_wr_data_byte0_we = 1; test_engine_new = TEST_GET_DATA1; test_engine_we = 1; end end TEST_GET_DATA1: begin if (!rx_buffer_empty) begin rx_buffer_rd_ptr_inc = 1; core_wr_data_byte1_we = 1; test_engine_new = TEST_GET_DATA2; test_engine_we = 1; end end TEST_GET_DATA2: begin if (!rx_buffer_empty) begin rx_buffer_rd_ptr_inc = 1; core_wr_data_byte2_we = 1; test_engine_new = TEST_GET_DATA3; test_engine_we = 1; end end TEST_GET_DATA3: begin if (!rx_buffer_empty) begin rx_buffer_rd_ptr_inc = 1; core_wr_data_byte3_we = 1; test_engine_new = TEST_GET_EOC; test_engine_we = 1; end end TEST_GET_EOC: begin if (!rx_buffer_empty) begin rx_buffer_rd_ptr_inc = 1; if (rx_byte == EOC) begin case (cmd_reg) RESET_CMD: begin test_engine_new = TEST_RST_START; test_engine_we = 1; end READ_CMD: begin test_engine_new = TEST_RD_START; test_engine_we = 1; end WRITE_CMD: begin test_engine_new = TEST_WR_START; test_engine_we = 1; end default: begin test_engine_new = TEST_CMD_UNKNOWN; test_engine_we = 1; end endcase // case (cmd_reg) end else begin test_engine_new = TEST_CMD_ERROR; test_engine_we = 1; end end end TEST_RST_START: begin core_reset_n_new = 0; core_reset_n_we = 1; test_engine_new = TEST_RST_WAIT; test_engine_we = 1; end TEST_RST_WAIT: begin test_engine_new = TEST_RST_END; test_engine_we = 1; end TEST_RST_END: begin core_reset_n_new = 1; core_reset_n_we = 1; update_tx_buffer = 1; response_type = RESET_OK; test_engine_new = TEST_SEND_RESPONSE; test_engine_we = 1; end TEST_RD_START: begin core_cs_new = 1; core_cs_we = 1; test_engine_new = TEST_RD_WAIT; test_engine_we = 1; end TEST_RD_WAIT: begin sample_core_output = 1; test_engine_new = TEST_RD_END; test_engine_we = 1; end TEST_RD_END: begin core_cs_new = 0; core_cs_we = 1; sample_core_output = 0; if (core_error_reg) begin update_tx_buffer = 1; response_type = ERROR; end else begin update_tx_buffer = 1; response_type = READ_OK; end test_engine_new = TEST_SEND_RESPONSE; test_engine_we = 1; end TEST_WR_START: begin core_cs_new = 1; core_cs_we = 1; core_we_new = 1; core_we_we = 1; test_engine_new = TEST_WR_WAIT; test_engine_we = 1; end TEST_WR_WAIT: begin sample_core_output = 1; test_engine_new = TEST_WR_END; test_engine_we = 1; end TEST_WR_END: begin core_cs_new = 0; core_cs_we = 1; core_we_new = 0; core_we_we = 1; sample_core_output = 0; if (core_error_reg) begin update_tx_buffer = 1; response_type = ERROR; end else begin update_tx_buffer = 1; response_type = WRITE_OK; end test_engine_new = TEST_SEND_RESPONSE; test_engine_we = 1; end TEST_CMD_UNKNOWN: begin update_tx_buffer = 1; response_type = UNKNOWN; test_engine_new = TEST_SEND_RESPONSE; test_engine_we = 1; end TEST_CMD_ERROR: begin update_tx_buffer = 1; response_type = ERROR; test_engine_new = TEST_SEND_RESPONSE; test_engine_we = 1; end TEST_SEND_RESPONSE: begin send_response_new = 1; send_response_we = 1; if (response_sent_reg) begin send_response_new = 0; send_response_we = 1; test_engine_new = TEST_IDLE; test_engine_we = 1; end end default: begin // If we encounter an unknown state we move // back to idle. test_engine_new = TEST_IDLE; test_engine_we = 1; end endcase // case (test_engine_reg) end // test_engine endmodule // coretest //====================================================================== // EOF coretest.v //======================================================================