`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