`include "common.svh" module sched_tb; typedef enum logic [7:0] { NOP = `NOP, R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31, ALU0, ALU1 } port_t; typedef logic [19:0] op_t; typedef struct packed { port_t src; port_t dst; } mov_t; typedef struct packed { mov_t[1:0] in; mov_t out; op_t op; } insn_t; typedef struct packed { mov_t[1:0] in; mov_t[0:0] out; op_t op; } slot_t; slot_t[1:0] prev_slots; slot_t[1:0] next_slots; insn_t[2:0] prev_que; insn_t[2:0] next_que; sched #( .QUE_DEPTH(3), .SLOT_COUNT(2), .SLOT_DEPTH(1), .port_t(port_t), .mov_t(mov_t), .insn_t(insn_t), .slot_t(slot_t) ) sched ( .que_i(prev_que), .que_o(next_que), .slots_i(prev_slots), .slots_o(next_slots) ); `define assert(signal, value) \ if (signal !== value) begin \ $error("%m: signal != value"); \ end slot_t[1:0] first_check = {68'b0, {R2, ALU0}, {R3, ALU0}, {ALU0, R1}, 20'h123}; slot_t[1:0] second_check = { {{R2, ALU0}, {R1, ALU0}, {ALU0, R5}, 20'h789}, {{R2, ALU1}, {R1, ALU1}, {ALU1, R4}, 20'h456} }; initial begin $dumpfile("sched_tb.vcd"); $dumpvars(); /* pretend we've queued something like * add r1, r2, r3 * add r4, r2, r1 * add r5, r2, r1 * * should end up with something like * add r1, r2, r3 noop * add r4, r2, r1 add r5, r2, r1 */ prev_que = { /* src2, src1, out, op, apparently. Have to get used to * systemverilog's way of laying out bits, huh. */ {{R2, ALU0}, {R1, ALU0}, {ALU0, R5}, 20'h789}, {{R2, ALU1}, {R1, ALU1}, {ALU1, R4}, 20'h456}, {{R2, ALU0}, {R3, ALU0}, {ALU0, R1}, 20'h123} /* also, 'reverse' order, first instruction at bottom */ }; prev_slots = '0; #10 assert (next_slots == first_check) else $error("\nwanted:\t%h", first_check, "\ngot:%h\t", next_slots); /* pretend all operations finished */ prev_slots = '0; prev_que = next_que; #10 assert (next_slots == second_check) else $error("\nwanted:\t%h", second_check, "\ngot:\t%h", next_slots); #10 $finish; end endmodule