aboutsummaryrefslogtreecommitdiff
path: root/src/rtl/coretest.v
diff options
context:
space:
mode:
Diffstat (limited to 'src/rtl/coretest.v')
-rw-r--r--src/rtl/coretest.v897
1 files changed, 897 insertions, 0 deletions
diff --git a/src/rtl/coretest.v b/src/rtl/coretest.v
new file mode 100644
index 0000000..92fab28
--- /dev/null
+++ b/src/rtl/coretest.v
@@ -0,0 +1,897 @@
+//======================================================================
+//
+// 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.
+ //----------------------------------------------------------------
+ // 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_SYN = 3'h1;
+ parameter RX_ACK = 3'h2;
+ parameter RX_CMD = 3'h3;
+ parameter RX_DONE = 3'h4;
+
+ // rx_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_PARSE_CMD = 8'h10;
+ 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_UNKNOWN = 8'h80;
+ 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 cmd_available_reg;
+ reg cmd_available_new;
+ reg cmd_available_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 [15 : 0] core_address_reg;
+ reg [31 : 0] core_write_data_reg;
+ reg [31 : 0] core_read_data_reg;
+ reg core_error_reg;
+ reg sample_core_output;
+
+ reg [3 : 0] rx_buffer_ptr_reg;
+ reg [3 : 0] rx_buffer_ptr_new;
+ reg rx_buffer_ptr_we;
+ reg rx_buffer_ptr_rst;
+ reg rx_buffer_ptr_inc;
+
+ reg [3 : 0] tx_buffer_ptr_reg;
+ reg [3 : 0] tx_buffer_ptr_new;
+ reg tx_buffer_ptr_we;
+ reg tx_buffer_ptr_rst;
+ reg tx_buffer_ptr_inc;
+
+ reg [7 : 0] rx_buffer [0 : 8];
+ reg rx_buffer_we;
+
+ reg [7 : 0] tx_buffer [0 : 8];
+ reg tx_buffer_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_buffert_muxed0;
+ reg [7 : 0] tx_buffert_muxed1;
+ reg [7 : 0] tx_buffert_muxed2;
+ reg [7 : 0] tx_buffert_muxed3;
+ reg [7 : 0] tx_buffert_muxed4;
+ reg [7 : 0] tx_buffert_muxed5;
+ reg [7 : 0] tx_buffert_muxed6;
+ reg [7 : 0] tx_buffert_muxed7;
+ reg [7 : 0] tx_buffert_muxed8;
+
+ reg extract_cmd_fields;
+
+ reg update_tx_buffer;
+ reg [7 : 0] response_type;
+
+ reg cmd_accepted;
+
+
+ //----------------------------------------------------------------
+ // 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_address_reg;
+ assign core_write_data = core_write_data_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;
+
+ 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_ptr_reg <= 4'h0;
+ tx_buffer_ptr_reg <= 4'h0;
+
+ send_response_reg <= 0;
+ response_sent_reg <= 0;
+
+ cmd_reg <= 8'h00;
+ cmd_available_reg <= 0;
+
+ core_reset_n_reg <= 1;
+ core_cs_reg <= 0;
+ core_we_reg <= 0;
+ core_error_reg <= 0;
+ core_address_reg <= 16'h0000;
+ core_write_data_reg <= 32'h00000000;
+ 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_ptr_reg] <= rx_data;
+ end
+
+ if (tx_buffer_we)
+ begin
+ tx_buffer[0] <= tx_buffert_muxed0;
+ tx_buffer[1] <= tx_buffert_muxed1;
+ tx_buffer[2] <= tx_buffert_muxed2;
+ tx_buffer[3] <= tx_buffert_muxed3;
+ tx_buffer[4] <= tx_buffert_muxed4;
+ tx_buffer[5] <= tx_buffert_muxed5;
+ tx_buffer[6] <= tx_buffert_muxed6;
+ tx_buffer[7] <= tx_buffert_muxed7;
+ tx_buffer[8] <= tx_buffert_muxed8;
+ end
+
+ if (rx_buffer_ptr_we)
+ begin
+ rx_buffer_ptr_reg <= rx_buffer_ptr_new;
+ end
+
+ if (tx_buffer_ptr_we)
+ begin
+ tx_buffer_ptr_reg <= tx_buffer_ptr_new;
+ end
+
+ if (extract_cmd_fields)
+ begin
+ cmd_reg <= rx_buffer[1];
+ core_address_reg <= {rx_buffer[2], rx_buffer[3]};
+ core_write_data_reg <= {rx_buffer[4], rx_buffer[5],
+ rx_buffer[6], rx_buffer[7]};
+ end
+
+ if (cmd_available_we)
+ begin
+ cmd_available_reg <= cmd_available_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
+
+
+ //---------------------------------------------------------------
+ // 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_buffert_muxed0 = 8'h00;
+ tx_buffert_muxed1 = 8'h00;
+ tx_buffert_muxed2 = 8'h00;
+ tx_buffert_muxed3 = 8'h00;
+ tx_buffert_muxed4 = 8'h00;
+ tx_buffert_muxed5 = 8'h00;
+ tx_buffert_muxed6 = 8'h00;
+ tx_buffert_muxed7 = 8'h00;
+ tx_buffert_muxed8 = 8'h00;
+
+ tx_buffer_we = 0;
+
+ if (update_tx_buffer)
+ begin
+ tx_buffer_we = 1;
+ tx_buffert_muxed0 = SOR;
+
+ case (response_type)
+ READ_OK:
+ begin
+ tx_buffert_muxed1 = READ_OK;
+ tx_buffert_muxed2 = core_address_reg[15 : 8];
+ tx_buffert_muxed3 = core_address_reg[7 : 0];
+ tx_buffert_muxed4 = core_read_data_reg[31 : 24];
+ tx_buffert_muxed5 = core_read_data_reg[23 : 16];
+ tx_buffert_muxed6 = core_read_data_reg[15 : 8];
+ tx_buffert_muxed7 = core_read_data_reg[7 : 0];
+ tx_buffert_muxed8 = EOR;
+ end
+
+ WRITE_OK:
+ begin
+ tx_buffert_muxed1 = WRITE_OK;
+ tx_buffert_muxed2 = core_address_reg[15 : 8];
+ tx_buffert_muxed3 = core_address_reg[7 : 0];
+ tx_buffert_muxed4 = EOR;
+ end
+
+ RESET_OK:
+ begin
+ tx_buffert_muxed1 = RESET_OK;
+ tx_buffert_muxed2 = EOR;
+ end
+
+ ERROR:
+ begin
+ tx_buffert_muxed1 = ERROR;
+ tx_buffert_muxed2 = cmd_reg;
+ tx_buffert_muxed3 = EOR;
+ end
+
+ default:
+ begin
+ // Any response type not explicitly defined is treated as UNKNOWN.
+ tx_buffert_muxed1 = UNKNOWN;
+ tx_buffert_muxed2 = cmd_reg;
+ tx_buffert_muxed3 = EOR;
+ end
+ endcase // case (response_type)
+ end
+ end // tx_buffer_logic
+
+
+ //----------------------------------------------------------------
+ // rx_buffer_ptr
+ //
+ // Logic for the rx buffer pointer. Supports reset and
+ // incremental updates.
+ //----------------------------------------------------------------
+ always @*
+ begin: rx_buffer_ptr
+ // Default assignments
+ rx_buffer_ptr_new = 4'h0;
+ rx_buffer_ptr_we = 0;
+
+ if (rx_buffer_ptr_rst)
+ begin
+ rx_buffer_ptr_new = 4'h0;
+ rx_buffer_ptr_we = 1;
+ end
+
+ else if (rx_buffer_ptr_inc)
+ begin
+ rx_buffer_ptr_new = rx_buffer_ptr_reg + 1'b1;
+ rx_buffer_ptr_we = 1;
+ end
+ end // rx_buffer_ptr
+
+
+ //----------------------------------------------------------------
+ // 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 = 0;
+
+ if (tx_buffer_ptr_rst)
+ begin
+ tx_buffer_ptr_new = 4'h0;
+ tx_buffer_ptr_we = 1;
+ end
+
+ else if (tx_buffer_ptr_inc)
+ begin
+ tx_buffer_ptr_new = tx_buffer_ptr_reg + 1'b1;
+ tx_buffer_ptr_we = 1;
+ end
+ end // tx_buffer_ptr
+
+
+ //----------------------------------------------------------------
+ // rx_engine
+ //
+ // FSM responsible for handling receiving message bytes from the
+ // host interface and signalling the test engine that there is
+ // a new command to be executed.
+ //----------------------------------------------------------------
+ always @*
+ begin: rx_engine
+ // Default assignments
+ rx_ack_new = 0;
+ rx_ack_we = 0;
+ rx_buffer_we = 0;
+ rx_buffer_ptr_rst = 0;
+ rx_buffer_ptr_inc = 0;
+ cmd_available_new = 0;
+ cmd_available_we = 0;
+ rx_engine_new = RX_IDLE;
+ rx_engine_we = 0;
+
+ case (rx_engine_reg)
+ RX_IDLE:
+ begin
+ if (rx_syn_reg)
+ begin
+ rx_buffer_we = 1;
+ rx_engine_new = RX_ACK;
+ rx_engine_we = 1;
+ end
+ end
+
+ RX_ACK:
+ begin
+ rx_ack_new = 1;
+ rx_ack_we = 1;
+
+ if (!rx_syn_reg)
+ begin
+ rx_ack_new = 0;
+ rx_ack_we = 1;
+
+ if (rx_buffer[rx_buffer_ptr_reg] == EOC)
+ begin
+ rx_engine_new = RX_DONE;
+ rx_engine_we = 1;
+ end
+
+ else
+ begin
+ rx_buffer_ptr_inc = 1;
+ rx_engine_new = RX_IDLE;
+ rx_engine_we = 1;
+ end
+ end
+ end
+
+ RX_DONE:
+ begin
+ cmd_available_new = 1;
+ cmd_available_we = 1;
+ rx_engine_new = RX_CMD;
+ rx_engine_we = 1;
+ end
+
+ RX_CMD:
+ if (cmd_accepted)
+ begin
+ cmd_available_new = 0;
+ cmd_available_we = 1;
+ rx_buffer_ptr_rst = 1;
+ rx_engine_new = RX_IDLE;
+ rx_engine_we = 1;
+ end
+
+ default:
+ begin
+ rx_buffer_ptr_rst = 1;
+ rx_engine_new = RX_IDLE;
+ rx_engine_we = 1;
+ 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_rst = 0;
+ tx_buffer_ptr_inc = 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[tx_buffer_ptr_reg] == EOR)
+ 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
+ tx_buffer_ptr_rst = 1;
+ response_sent_new = 0;
+ response_sent_we = 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;
+ cmd_accepted = 0;
+ extract_cmd_fields = 0;
+ sample_core_output = 0;
+ update_tx_buffer = 0;
+ response_type = 8'h00;
+ 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 (cmd_available_reg)
+ begin
+ extract_cmd_fields = 1;
+ test_engine_new = TEST_PARSE_CMD;
+ test_engine_we = 1;
+ end
+ end
+
+ TEST_PARSE_CMD:
+ begin
+ cmd_accepted = 1;
+
+ 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
+ // Unknown command.
+ test_engine_new = TEST_UNKNOWN;
+ test_engine_we = 1;
+ end
+ endcase // case (cmd_reg)
+ 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_UNKNOWN:
+ begin
+ update_tx_buffer = 1;
+ response_type = UNKNOWN;
+ 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
+//======================================================================