aboutsummaryrefslogtreecommitdiff
`default_nettype none

`include "messages.vh"

`ifndef SIMULATION
 `error_SIMULATION_not_defined
; /* Cause syntax error */
`endif

`ifndef INSTRUCTIONS_COUNT
 `error_INSTRUCTIONS_COUNT_must_be_defined
; /* Cause syntax error */
`endif

`ifndef WORDS_TO_VERIFY_COUNT
 `error_WORDS_TO_VERIFY_COUNT_must_be_defined
; /* Cause syntax error */
`endif

module wasm_compile_test();
   reg         CLK;
   reg         RST;

   /*
    * Master 0 is stack machine's wrapped data interface.
    * Master 1 is stack machine's instructions interface.
    */
   wire        M0_ACK_I,   M1_ACK_I;
   wire [19:0] M0_ADR_O,   M1_ADR_O;
   wire [15:0] M0_DAT_I,   M1_DAT_I;
   wire [15:0] M0_DAT_O,   M1_DAT_O;
   wire        M0_STB_O,   M1_STB_O;
   wire        M0_CYC_O,   M1_CYC_O;
   wire        M0_WE_O,    M1_WE_O;
   wire        M0_STALL_I, M1_STALL_I;

   wire        S_ACK_O;
   wire [19:0] S_ADR_I;
   wire [15:0] S_DAT_I;
   wire [15:0] S_DAT_O;
   wire        S_SEL_I;
   wire        S_STB_I;
   wire        S_WE_I;
   wire        S_STALL_O;

   wire        M_COMBINED_ACK_I;
   wire [19:0] M_COMBINED_ADR_O;
   wire [15:0] M_COMBINED_DAT_I;
   wire [15:0] M_COMBINED_DAT_O;
   wire        M_COMBINED_STB_O;
   wire        M_COMBINED_CYC_O;
   wire        M_COMBINED_WE_O;
   wire        M_COMBINED_STALL_I;

   /* Non-wishbone */
   wire        M_finished;

   wrapped_stack_machine stack_machine
     (
      .CLK_I(CLK),
      .RST_I(RST),

      /* Instruction reading interface */
      .I_ACK_I(M1_ACK_I),
      .I_ADR_O(M1_ADR_O),
      .I_DAT_I(M1_DAT_I),
      .I_DAT_O(M1_DAT_O),
      .I_STB_O(M1_STB_O),
      .I_CYC_O(M1_CYC_O),
      .I_WE_O(M1_WE_O),
      .I_STALL_I(M1_STALL_I),

      /* Data interface */
      .D_ACK_I(M0_ACK_I),
      .D_ADR_O(M0_ADR_O),
      .D_DAT_I(M0_DAT_I),
      .D_DAT_O(M0_DAT_O),
      .D_STB_O(M0_STB_O),
      .D_CYC_O(M0_CYC_O),
      .D_WE_O(M0_WE_O),
      .D_STALL_I(M0_STALL_I),

      .finished(M_finished)
      );

   memory_slave_model
     #(
       .SLAVE_NR(0),
       .WORD_SIZE(2),
       .ADR_BITS(20),
       .WRITABLE(1),
       .WORDS_TO_INITIALIZE(`INSTRUCTIONS_COUNT),
       .INITIAL_CONTENTS_FILE("instructions.mem")
       ) slave
       (
	.ACK_O(S_ACK_O),
      	.CLK_I(CLK),
	.ADR_I(S_ADR_I),
	.DAT_I(S_DAT_I),
	.DAT_O(S_DAT_O),
	.SEL_I(S_SEL_I),
      	.RST_I(RST),
      	.STB_I(S_STB_I),
      	.WE_I(S_WE_I),
	.STALL_O(S_STALL_O)
	);

   master_arbiter arbiter
     (
      .CLK(CLK),
      .RST(RST),

      .M0_ACK_I(M0_ACK_I),
      .M0_ADR_O(M0_ADR_O),
      .M0_DAT_I(M0_DAT_I),
      .M0_DAT_O(M0_DAT_O),
      .M0_STB_O(M0_STB_O),
      .M0_CYC_O(M0_CYC_O),
      .M0_WE_O(M0_WE_O),
      .M0_STALL_I(M0_STALL_I),

      .M1_ACK_I(M1_ACK_I),
      .M1_ADR_O(M1_ADR_O),
      .M1_DAT_I(M1_DAT_I),
      .M1_DAT_O(M1_DAT_O),
      .M1_STB_O(M1_STB_O),
      .M1_CYC_O(M1_CYC_O),
      .M1_WE_O(M1_WE_O),
      .M1_STALL_I(M1_STALL_I),

      .M_COMBINED_ACK_I(M_COMBINED_ACK_I),
      .M_COMBINED_ADR_O(M_COMBINED_ADR_O),
      .M_COMBINED_DAT_I(M_COMBINED_DAT_I),
      .M_COMBINED_DAT_O(M_COMBINED_DAT_O),
      .M_COMBINED_STB_O(M_COMBINED_STB_O),
      .M_COMBINED_CYC_O(M_COMBINED_CYC_O),
      .M_COMBINED_WE_O(M_COMBINED_WE_O),
      .M_COMBINED_STALL_I(M_COMBINED_STALL_I)
      );

   assign M_COMBINED_ACK_I = S_ACK_O;
   assign M_COMBINED_DAT_I = S_DAT_O;
   assign M_COMBINED_STALL_I = S_STALL_O;

   assign S_ADR_I = M_COMBINED_ADR_O;
   assign S_DAT_I = M_COMBINED_DAT_O;
   assign S_SEL_I = 1;
   assign S_STB_I = M_COMBINED_STB_O && M_COMBINED_CYC_O;
   assign S_WE_I = M_COMBINED_WE_O;

   integer     i, j, k;
   reg [20:0]  address;
   reg [31:0]  expected_value;
   reg [31:0]  found_value;

   reg [31:0]  words_to_verify[`WORDS_TO_VERIFY_COUNT * 2 - 1 : 0];

   initial begin
      CLK <= 0;
      RST <= 1;

      for (i = 0; i < 20000; i++) begin
	 #1;

	 CLK <= ~CLK;

	 if (CLK)
	   RST <= 0;

	 if (M_finished) begin
	    $readmemh("words_to_verify.mem", words_to_verify,
		      0, `WORDS_TO_VERIFY_COUNT * 2 - 1);

	    for (j = 0; j < `WORDS_TO_VERIFY_COUNT; j++) begin
	       address = words_to_verify[2 * j][21:0];
	       expected_value = words_to_verify[2 * j + 1];

	       for (k = 0; k < 4; k++) begin
		  found_value[23:0] = found_value[31:8];

		  found_value[31:24] = address[0] ?
				     slave.memory[address >> 1][15:8] :
				     slave.memory[address >> 1][7:0];
		  address += 1;
	       end

	       address -= 4;

	       if (found_value !== expected_value) begin
		  $display("error: expected h%x at h%x, but got h%x",
			   expected_value, address, found_value);
	       end
	    end

	    $finish;
	 end // if (M_finished)
      end // for (i = 0; i < 20000; i++)

      $display("error: cpu hasn't finished its operations in 10000 ticks");
      $finish;
   end // initial begin
endmodule // stack_machine_test