module arb_tb; localparam WIDTH = 32; reg clk; reg rstx; logic[WIDTH-1:0] valid; logic[WIDTH-1:0] selected; arb #( .WIDTH(32) ) arb_i ( .clk(clk), .rstx(rstx), .valid(valid), .selected(selected) ); initial begin clk = 0; forever begin #5 clk = ~clk; end end initial begin $dumpfile("arb_tb.fst"); $dumpvars(); /* trigger resets */ rstx = 0; #10 rstx = 1; /* honestly, I'm a bit confused about this, if I try to make this be at * a positive clock edge, the selected == 1 condition disappears because * valid apparently triggers `selected` to be recalculated first, which * then is fed into `mask` which then re-triggers `selected` and causes * it to 'skip' ahead to selected == 2. When looking at the waveforms, * the next @(posedge clk) shows 2 while the assert passes. I guess the * assert is run first in the time step...? */ valid = ~0; @(posedge clk); assert (selected == 1) else $error("expected 1, got ", selected); @(posedge clk); assert (selected == 2) else $error("expected 2, got ", selected); /* wait one clock cycle, should move forward by one */ @(posedge clk); assert (selected == 4) else $error("expected 4, got ", selected); /* skip next index */ valid = '0; @(posedge clk); assert (selected == 0) else $error("expected 0, got ", selected); valid = ~8; @(posedge clk); assert (selected == 16) else $error("expected 16, got ", selected); /* check that ID wraps around nicely */ for (int i = 0; i < 32 - 4; ++i) @(posedge clk); assert (selected == 1) else $error("wraparound broken, expected 1, got ", selected); $finish; end endmodule