Might not be as optimized a solution like Dave provided. But this works for me.
class instr;
typedef enum {
ADD,
MUL,
SUB,
NOP
} instr_t;
rand instr_t ins;
instr_t last3_valid_instr_q[$];
instr_t last4_instr_q[$];
instr_t last3_instr_q[$];
//No add instruction is repeated in 3 clock cycles
constraint c1 {
ADD inside {last3_instr_q} -> ins != ADD;
}
//MUL is not repeated in 4 clock cycles
constraint c2 {
MUL inside {last4_instr_q} -> ins != MUL;
}
//SUB is not repeated in the last 3 valid instructions.
constraint c3 {
SUB inside {last3_valid_instr_q} -> ins != SUB;
}
function void post_randomize();
//Populating last3_valid_instr_q
if(ins != NOP) begin
if(last3_valid_instr_q.size == 3)
last3_valid_instr_q.pop_front;
last3_valid_instr_q.push_back(ins);
end
//populating last4_instr_q
if(last4_instr_q.size == 4)
last4_instr_q.pop_front;
last4_instr_q.push_back(ins);
//populating last3_instr_q
if(last3_instr_q.size == 3)
last3_instr_q.pop_front;
last3_instr_q.push_back(ins);
endfunction
endclass
module top;
initial begin
instr in;
in = new;
repeat(100) begin
in.randomize();
$display("%p",in.ins);
end
end
endmodule