Initial snapshot from fall_26_member
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Builds programs and external-port transactions, then sends them to the
|
||||
* driver through xbar_box. The sequencer describes intent but never drives or
|
||||
* observes the DUT directly.
|
||||
*/
|
||||
class cpu_sequencer #(int DataSize=32, int AddrSize=14);
|
||||
|
||||
mailbox #(cpu_xbar_item #(DataSize, AddrSize)) xbar_box;
|
||||
|
||||
// Constructor
|
||||
function new();
|
||||
xbar_box = new();
|
||||
endfunction: new
|
||||
|
||||
// Build a random program and enqueue frontdoor instruction writes.
|
||||
// idx and prog_len are assigned before randomization because branch
|
||||
// constraints depend on the instruction's position.
|
||||
task gen_program(input int num, input bit verbose=1'b1);
|
||||
cpu_seq_item #(DataSize, AddrSize) instr;
|
||||
int prog_len;
|
||||
|
||||
prog_len = num + 1; // +1 for the ebreak
|
||||
|
||||
for (int i = 0; i < num; i++) begin
|
||||
instr = new();
|
||||
instr.idx = i;
|
||||
instr.prog_len = prog_len;
|
||||
if (!instr.randomize()) begin
|
||||
$error($stime, " Seq: randomization failed for instruction %0d\n", i);
|
||||
end
|
||||
if (verbose) begin
|
||||
instr.display();
|
||||
end
|
||||
send_write_trans(word_addr(ISRAM_BASE, i), instr.encode());
|
||||
end
|
||||
|
||||
// Append ebreak explicitly so a random program cannot halt early
|
||||
instr = new();
|
||||
instr.idx = num;
|
||||
instr.prog_len = prog_len;
|
||||
instr.op = OP_EBREAK;
|
||||
instr.rs1 = '0;
|
||||
instr.rs2 = '0;
|
||||
instr.rd = '0;
|
||||
instr.imm = 0;
|
||||
if (verbose) begin
|
||||
instr.display();
|
||||
end
|
||||
send_write_trans(word_addr(ISRAM_BASE, num), instr.encode());
|
||||
endtask: gen_program
|
||||
|
||||
// Stage one external write transaction
|
||||
task send_write_trans(input logic [AddrSize-1:0] addr, input logic [DataSize-1:0] data);
|
||||
cpu_xbar_item #(DataSize, AddrSize) trans;
|
||||
|
||||
trans = new();
|
||||
trans.kind = XBAR_WRITE;
|
||||
trans.addr = addr;
|
||||
trans.data = data;
|
||||
trans.is_write = 1'b1;
|
||||
xbar_box.put(trans);
|
||||
endtask: send_write_trans
|
||||
|
||||
// Stage one external read transaction
|
||||
task send_read_trans(input logic [AddrSize-1:0] addr);
|
||||
cpu_xbar_item #(DataSize, AddrSize) trans;
|
||||
|
||||
trans = new();
|
||||
trans.kind = XBAR_READ;
|
||||
trans.addr = addr;
|
||||
trans.is_write = 1'b0;
|
||||
xbar_box.put(trans);
|
||||
endtask: send_read_trans
|
||||
|
||||
// Stage a program as instruction-memory writes starting at word zero
|
||||
task load_program(const ref logic [31:0] prog [$]);
|
||||
foreach (prog[i]) begin
|
||||
send_write_trans(word_addr(ISRAM_BASE, i), prog[i]);
|
||||
end
|
||||
endtask: load_program
|
||||
|
||||
// Generate external-port traffic. cpu_xbar_item constraints define the
|
||||
// useful behavior; the mailbox mechanics are supplied.
|
||||
task gen_xbar(input int num, input bit verbose=1'b0);
|
||||
cpu_xbar_item #(DataSize, AddrSize) trans;
|
||||
|
||||
for (int i = 0; i < num; i++) begin
|
||||
trans = new();
|
||||
if (!trans.randomize()) begin
|
||||
$error($stime, " Seq: randomization failed for xbar item %0d\n", i);
|
||||
end
|
||||
if (verbose) begin
|
||||
trans.display();
|
||||
end
|
||||
xbar_box.put(trans);
|
||||
end
|
||||
endtask: gen_xbar
|
||||
|
||||
// Wait until the driver has pulled every staged mailbox transaction
|
||||
task wait_for_empty();
|
||||
while (xbar_box.num() != 0) begin
|
||||
#10;
|
||||
end
|
||||
endtask: wait_for_empty
|
||||
|
||||
endclass: cpu_sequencer
|
||||
Reference in New Issue
Block a user