Skip to content

Commit

Permalink
exec almost complete
Browse files Browse the repository at this point in the history
  • Loading branch information
Utkarsh Mathur committed Apr 19, 2018
1 parent a962abc commit b2894a1
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 97 deletions.
13 changes: 9 additions & 4 deletions tb/agent.sv
@@ -1,7 +1,7 @@
// Class for common functionality between monitor and driver
class Agent;
integer num_assert = 0;
integer fail_assert = 0;
integer num_assert[ string ];
integer fail_assert[ string ];

virtual function void printInstMemIndex( integer index );
check("AGENT", FATAL, index >= 0 && index < top.test.env.instMem.size(),
Expand Down Expand Up @@ -33,9 +33,14 @@ class Agent;

// assert
virtual function void check(string stage, severityT severity, reg cond, string A);
num_assert += 1;
if( !num_assert.exists(stage) ) begin
num_assert [stage] = 0;
fail_assert[stage] = 0;
end

num_assert[stage] += 1;
if(!cond) begin
fail_assert += 1;
fail_assert[stage] += 1;
if( severity == FATAL ) begin
$fatal(1, "%t [CHECKER.%s] %s", $time, stage, A);
void'(top.test.eos());
Expand Down
192 changes: 103 additions & 89 deletions tb/monitor.sv
Expand Up @@ -27,7 +27,7 @@ class Monitor extends Agent;
reg [1:0] decode_Wctrl;
// TODO: do we really need this? DUT is inconsistent
// with IR based lookup
reg decode_ECtrl_skip;
reg decode_init;

/*
* Execute globals
Expand All @@ -37,6 +37,11 @@ class Monitor extends Agent;
reg [15:0] exec_npc;
reg [1:0] exec_bypass1;
reg [1:0] exec_bypass2;
reg [15:0] exec_aluout;
reg [15:0] exec_vsr1, exec_vsr2;
reg [1:0] exec_Wctrl;
reg exec_Mctrl;
reg exec_init;

/*
* Mem globals
Expand Down Expand Up @@ -92,11 +97,13 @@ class Monitor extends Agent;
$psprintf("Unmatched IR (%0x != %0x, Opcode: %s != %s)", decode_ir, decodeIf.IR,
Instruction::op2str(decode_ir[15:12]), Instruction::op2str(decodeIf.IR[15:12])) );

if( decode_ECtrl_skip ) begin
//Hazard prone
check("DECODE", WARN, decode_Ectrl == decodeIf.E_Control, $psprintf("[%s] E_control unmatched! (%0b != %0x)",
Instruction::op2str(decode_ir[15:12]), decode_Ectrl, decodeIf.E_Control));
if( decode_init ) begin
decode_Ectrl = 0;
end

//Hazard prone
check("DECODE", WARN, decode_Ectrl == decodeIf.E_Control, $psprintf("[%s] E_control unmatched! (%0b != %0x)",
Instruction::op2str(decode_ir[15:12]), decode_Ectrl, decodeIf.E_Control));
check("DECODE", WARN, decode_Wctrl === decodeIf.W_Control, $psprintf("[%s] W_control unmatched! (%0x != %0x)",
Instruction::op2str(decode_ir[15:12]), decode_Wctrl, decodeIf.W_Control));
check("DECODE", WARN, decode_Mctrl === decodeIf.Mem_Control, $psprintf("[%s] Mem_control unmatched! (%0x != %0x)",
Expand All @@ -105,159 +112,166 @@ class Monitor extends Agent;

decode_ir = ctrlrIf.Instr_dout;
decode_npcout = fetchIf.npc;
decode_ECtrl_skip = 1;
decode_init = 0;
end //}

// Reset state
if( monIf.reset ) begin
decode_ir = 0;
decode_npcout = 0;
decode_ECtrl_skip = 0;
decode_init = 1;
end

endfunction //}

function void execute(); //{

reg [1:0] exe_Wctrl_out;
reg exe_Mctrl_out;
reg [2:0] exe_dr;
reg [2:0] exe_sr1;
reg [2:0] exe_sr2;
reg [2:0] exe_nzp;
reg [15:0] exe_M_data;

logic [15:0] exe_aluout;
logic [15:0] exe_pcout;
logic [15:0] exec_pcout;
logic [15:0] val_1;
logic [15:0] val_2;
logic [2:0] exec_nzp;
logic [2:0] exec_dr;
logic [15:0] exec_Mdata;

if( !monIf.reset && ctrlrIf.enable_execute ) begin //{
//reconfiguring offsets in execute
//for PC OUT
case(exec_bypass1)
2'b00: val_1 = wbIf.VSR1;
2'b00: val_1 = exec_vsr1;
2'b01: val_1 = memIf.memout;
2'b10: val_1 = execIf.aluout;
2'b10: val_1 = exec_aluout;
endcase

case(exec_bypass2)
2'b00: val_2 = exec_Ectrl[0] ? wbIf.VSR2 : {{11{exec_IR[4]}}, exec_IR[4:0]};
2'b00: val_2 = exec_Ectrl[0] ? exec_vsr2 : {{11{exec_IR[4]}}, exec_IR[4:0]};
2'b01: val_2 = memIf.memout;
2'b10: val_2 = execIf.aluout;
2'b10: val_2 = exec_aluout;
endcase

case(exec_Ectrl[3:2])
2'b00: begin exe_pcout = {{5{exec_IR[10]}}, exec_IR[10:0]} + (exec_Ectrl[1] ? exec_npc : val_1); end
2'b01: begin exe_pcout = {{7{exec_IR[8]}} , exec_IR[8:0]} + (exec_Ectrl[1] ? exec_npc : val_1); end
2'b10: begin exe_pcout = {{10{exec_IR[5]}}, exec_IR[5:0]} + (exec_Ectrl[1] ? exec_npc : val_1); end
2'b11: begin exe_pcout = 16'b0; end
2'b00: begin exec_pcout = {{5{exec_IR[10]}}, exec_IR[10:0]} + (exec_Ectrl[1] ? exec_npc : val_1); end
2'b01: begin exec_pcout = {{7{exec_IR[8]}} , exec_IR[8:0]} + (exec_Ectrl[1] ? exec_npc : val_1); end
2'b10: begin exec_pcout = {{10{exec_IR[5]}}, exec_IR[5:0]} + (exec_Ectrl[1] ? exec_npc : val_1); end
2'b11: begin exec_pcout = 16'b0; end
endcase

//ALU Control unit
case(exec_Ectrl[5:4])
2'b00: begin exe_aluout = val_1 + val_2; end
2'b01: begin exe_aluout = val_1 & val_2; end
2'b10: begin exe_aluout = ~val_1; end
default: begin check("EXECUTE", FATAL, 1, "Control not supported"); end
2'b00: begin exec_aluout = val_1 + val_2; end
2'b01: begin exec_aluout = val_1 & val_2; end
2'b10: begin exec_aluout = ~val_1; end
default: begin check("EXEC", FATAL, 1, "Control not supported"); end
endcase

$display("%0x %0b %0b %0b %0x %0x %0x %0x %0x", exec_IR, exec_bypass1, exec_bypass2, exec_Ectrl[5:4], val_1, val_2, wbIf.VSR1, wbIf.VSR2, exec_IR[4:0]);
//TODO: SR1 and SR2
//TODO: Why don't care for mem data?
// For ALU, short alout with pcout (not documented)
exe_M_data = 16'bx;
exec_Mdata = 16'bx;
case(exec_IR[15:12])
ADD: begin exe_dr = exec_IR[11:9]; exe_nzp = 3'b000; exe_pcout = exe_aluout; end
AND: begin exe_dr = exec_IR[11:9]; exe_nzp = 3'b000; exe_pcout = exe_aluout; end
NOT: begin exe_dr = exec_IR[11:9]; exe_nzp = 3'b000; exe_pcout = exe_aluout; end
LD : begin exe_dr = exec_IR[11:9]; exe_nzp = 3'b000; end
LDR: begin exe_dr = exec_IR[11:9]; exe_nzp = 3'b000; end
LDI: begin exe_dr = exec_IR[11:9]; exe_nzp = 3'b000; end
LEA: begin exe_dr = exec_IR[11:9]; exe_nzp = 3'b000; end
ST : begin exe_dr = 3'b0; exe_nzp = 3'b000; exe_M_data = val_1; end
STR: begin exe_dr = 3'b0; exe_nzp = 3'b000; exe_M_data = val_1; end
STI: begin exe_dr = 3'b0; exe_nzp = 3'b000; exe_M_data = val_1; end
BR : begin exe_dr = 3'b0; exe_nzp = execIf.IR_Exec[11:9]; end
JMP: begin exe_dr = 3'b0; exe_nzp = 3'b111; end
ADD: begin exec_dr = exec_IR[11:9]; exec_nzp = 3'b000; exec_Mdata = val_1; exec_pcout = exec_aluout; end
AND: begin exec_dr = exec_IR[11:9]; exec_nzp = 3'b000; exec_Mdata = val_1; exec_pcout = exec_aluout; end
NOT: begin exec_dr = exec_IR[11:9]; exec_nzp = 3'b000; exec_Mdata = val_1; exec_pcout = exec_aluout; end
LD : begin exec_dr = exec_IR[11:9]; exec_nzp = 3'b000; exec_Mdata = val_1; exec_aluout = exec_pcout; end
LDR: begin exec_dr = exec_IR[11:9]; exec_nzp = 3'b000; exec_Mdata = val_1; exec_aluout = exec_pcout; end
LDI: begin exec_dr = exec_IR[11:9]; exec_nzp = 3'b000; exec_Mdata = val_1; exec_aluout = exec_pcout; end
LEA: begin exec_dr = exec_IR[11:9]; exec_nzp = 3'b000; exec_Mdata = val_1; exec_aluout = exec_pcout; end
ST : begin exec_dr = 3'b0; exec_nzp = 3'b000; exec_Mdata = val_1; exec_aluout = exec_pcout; end
STR: begin exec_dr = 3'b0; exec_nzp = 3'b000; exec_Mdata = val_1; exec_aluout = exec_pcout; end
STI: begin exec_dr = 3'b0; exec_nzp = 3'b000; exec_Mdata = val_1; exec_aluout = exec_pcout; end
BR : begin exec_dr = 3'b0; exec_nzp = exec_IR[11:9];exec_Mdata = val_1; exec_aluout = exec_pcout; end
JMP: begin exec_dr = 3'b0; exec_nzp = 3'b111; exec_Mdata = val_1; end
endcase

//check("EXECUTE", WARN, decodeIf.W_Control === execIf.W_Control_out, $psprintf("[%s] W_control unmatched! (%0x != %0x)",
// Instruction::op2str(execIf.IR_Exec[15:12]), decodeIf.W_Control, execIf.W_Control_out));
if( exec_init ) begin
exec_Wctrl = 0;
exec_Mctrl = 0;
exec_aluout = 0;
exec_pcout = 0;
end

check("EXEC", WARN, exec_Wctrl === execIf.W_Control_out, $psprintf("[%s] W_control unmatched! (%0x != %0x)",
Instruction::op2str(exec_IR[15:12]), exec_Wctrl, execIf.W_Control_out));

//check("EXECUTE", WARN, decodeIf.Mem_Control === execIf.Mem_Control_out, $psprintf("[%s] Mem_control unmatched! (%0x != %0x)",
// Instruction::op2str(execIf.IR_Exec[15:12]), decodeIf.Mem_Control, execIf.Mem_Control_out));
check("EXEC", WARN, exec_Mctrl === execIf.Mem_Control_out, $psprintf("[%s] Mem_control unmatched! (%0x != %0x)",
Instruction::op2str(exec_IR[15:12]), exec_Mctrl, execIf.Mem_Control_out));

//check("EXECUTE", WARN, exe_aluout === execIf.aluout, $psprintf("[%s] alu out unmatched! (%0x != %0x)",
// Instruction::op2str(execIf.IR_Exec[15:12]), exe_aluout, execIf.aluout));
check("EXEC", WARN, exec_aluout === execIf.aluout, $psprintf("[%s] alu out unmatched! (%0x != %0x)",
Instruction::op2str(exec_IR[15:12]), exec_aluout, execIf.aluout));

check("EXECUTE", WARN, exe_pcout === execIf.pcout, $psprintf("[%s] pc out unmatched! (%0x != %0x)",
Instruction::op2str(exec_IR[15:12]), exe_pcout, execIf.pcout));
check("EXEC", WARN, exec_pcout === execIf.pcout, $psprintf("[%s] pc out unmatched! (%0x != %0x)",
Instruction::op2str(exec_IR[15:12]), exec_pcout, execIf.pcout));

//check("EXECUTE", WARN, exe_dr === execIf.dr, $psprintf("[%s] destination register unmatched! (%0x != %0x)",
// Instruction::op2str(execIf.IR_Exec[15:12]), exe_dr, execIf.dr));
check("EXEC", WARN, exec_dr === execIf.dr, $psprintf("[%s] destination register unmatched! (%0x != %0x)",
Instruction::op2str(exec_IR[15:12]), exec_dr, execIf.dr));

////check("EXECUTE", WARN, exe_sr1 === execIf.sr1, $psprintf("[%s] source one register unmatched! (%0x != %0x)",
////check("EXEC", WARN, exe_sr1 === execIf.sr1, $psprintf("[%s] source one register unmatched! (%0x != %0x)",
//// Instruction::op2str(execIf.IR_Exec[15:12]), exe_sr1, execIf.sr1));

////check("EXECUTE", WARN, exe_sr2 === execIf.sr2, $psprintf("[%s] source two register unmatched! (%0x != %0x)",
////check("EXEC", WARN, exe_sr2 === execIf.sr2, $psprintf("[%s] source two register unmatched! (%0x != %0x)",
//// Instruction::op2str(execIf.IR_Exec[15:12]), exe_sr2, execIf.sr2));

//check("EXECUTE", WARN, exe_nzp === execIf.NZP, $psprintf("[%s] NZP unmatched! (%0x != %0x)",
// Instruction::op2str(execIf.IR_Exec[15:12]), exe_nzp, execIf.NZP));
check("EXEC", WARN, exec_nzp === execIf.NZP, $psprintf("[%s] NZP unmatched! (%0x != %0x)",
Instruction::op2str(exec_IR[15:12]), exec_nzp, execIf.NZP));

check("EXEC", WARN, exec_IR === execIf.IR_Exec, $psprintf("[%s] IR Execute unmatched! (%0x != %0x)",
Instruction::op2str(exec_IR[15:12]), exec_IR, execIf.IR_Exec));

//check("EXECUTE", WARN, execute_ir === execIf.IR_Exec, $psprintf("[%s] IR Execute unmatched! (%0x != %0x)",
// Instruction::op2str(execIf.IR_Exec[15:12]), execute_ir, execIf.IR_Exec));
//check("EXEC", WARN, exec_Mdata === execIf.M_Data, $psprintf("[%s] mem data unmatched! (%0x != %0x)",
// Instruction::op2str(exec_IR[15:12]), exec_Mdata, execIf.M_Data));

//check("EXECUTE", WARN, exe_M_data === execIf.M_Data, $psprintf("[%s] mem data unmatched! (%0x != %0x)",
// Instruction::op2str(execIf.IR_Exec[15:12]), exe_M_data, execIf.M_Data));
//$display("%0x %0b %0b %0b %0x %0x %0x %0x %0x %0x %0x %0x %0x", exec_IR, exec_bypass1, exec_bypass2, exec_Ectrl[5:4], val_1, val_2, exec_vsr1, exec_vsr2, exec_IR[4:0], exec_aluout, execIf.aluout, execIf.pcout, execIf.sr1);

exec_Ectrl = decodeIf.E_Control;
exec_Wctrl = decodeIf.W_Control;
exec_Mctrl = decodeIf.Mem_Control;
exec_IR = decodeIf.IR;
exec_npc = decodeIf.npc_out;
exec_init = 0;
end //}

exec_bypass1 = {ctrlrIf.bypass_alu_1, ctrlrIf.bypass_mem_1};
exec_bypass2 = {ctrlrIf.bypass_alu_2, ctrlrIf.bypass_mem_2};
exec_vsr1 = wbIf.VSR1;
exec_vsr2 = wbIf.VSR2;

if( monIf.reset ) begin
exec_Ectrl = 0;
exec_IR = 0;
exec_npc = 0;
exec_init = 1;
end
endfunction //}

/*function void memAccess();
reg mem_Dmem_rd;
reg [15:0] mem_Dmem_din;
reg [15:0] mem_Dmem_addr;
begin //{
case(ctrlrIf.mem_state)
2'b00: begin //{
mem_Dmem_rd = 1;
mem_Dmem_din = 0;
mem_Dmem_addr = (execIf.Mem_Control_out) ? memIf.Data_dout : execIf.pcout;
end //}
2'b01: begin //{
mem_Dmem_rd = (execIf.Mem_Control_out) ? 1 : 0;
mem_Dmem_din = 0;
mem_Dmem_addr = execIf.pcout;
end//}
2'b10: begin //{
mem_Dmem_rd = 0;
mem_Dmem_din = execIf.M_Data;
mem_Dmem_addr = (execIf.Mem_Control_out) ? memIf.Data_dout : execIf.pcout;
end//}
2'b11: begin //{
mem_Dmem_rd = 1'bz;
mem_Dmem_din = 16'hz;
mem_Dmem_addr = 16'hz;
end //}
endcase
end //}
endfunction*/
//function void memAccess();
// reg mem_Dmem_rd;
// reg [15:0] mem_Dmem_din;
// reg [15:0] mem_Dmem_addr;
// case(ctrlrIf.mem_state)
// 2'b00: begin //{
// mem_Dmem_rd = 1;
// mem_Dmem_din = 0;
// mem_Dmem_addr = (execIf.Mem_Control_out) ? memIf.Data_dout : execIf.pcout;
// end //}
// 2'b01: begin //{
// mem_Dmem_rd = (execIf.Mem_Control_out) ? 1 : 0;
// mem_Dmem_din = 0;
// mem_Dmem_addr = execIf.pcout;
// end//}
// 2'b10: begin //{
// mem_Dmem_rd = 0;
// mem_Dmem_din = execIf.M_Data;
// mem_Dmem_addr = (execIf.Mem_Control_out) ? memIf.Data_dout : execIf.pcout;
// end//}
// 2'b11: begin //{
// mem_Dmem_rd = 1'bz;
// mem_Dmem_din = 16'hz;
// mem_Dmem_addr = 16'hz;
// end //}
// endcase
//endfunction

//function void controller();
//begin //{
Expand Down
30 changes: 26 additions & 4 deletions tb/test.sv
Expand Up @@ -17,7 +17,7 @@ class Test; //{
// all tests. It doesn't have LD/SD and BR as mem warmup
// is not done
virtual function void sequenceInstr();
integer numTrans = 8 + 10;
integer numTrans = 8 + 15;
Instruction instMemEntry = new;
env.instMem = new [numTrans];
for( int i = 0; i < 8; i++ ) begin
Expand Down Expand Up @@ -95,14 +95,36 @@ class Test; //{

// End of simulation function
function void eos( bit passReport=1 );
string stage;
integer mon_num_assert = 0, mon_fail_assert = 0;
integer dri_num_assert = 0, dri_fail_assert = 0;
$display("----------- END OF TEST -------------");
$display("----------- BEGIN REPORT ------------");
if( passReport ) begin
$display("Stats [Driver ]: %0d / %0d Evaluations Failed", env.driver.fail_assert, env.driver.num_assert);
$display("Stats [Monitor]: %0d / %0d Evaluations Failed", env.monitor.fail_assert, env.monitor.num_assert);
$display("Stats [Driver ]: ");
if( env.driver.num_assert.first(stage) ) begin
do begin
dri_num_assert += env.driver.num_assert[stage];
dri_fail_assert += env.driver.fail_assert[stage];
$display(" [%s\t]\t%0d / %0d Evaluations Failed", stage, env.driver.fail_assert[stage], env.driver.num_assert[stage]);
end
while( env.driver.num_assert.next(stage) );
end
$display(" [TOTAL\t]\t%0d / %0d Evaluations Failed", dri_fail_assert, dri_num_assert);

$display("\nStats [Monitor]: ");
if( env.monitor.num_assert.first(stage) ) begin
do begin
mon_num_assert += env.monitor.num_assert[stage];
mon_fail_assert += env.monitor.fail_assert[stage];
$display(" [%s\t]\t%0d / %0d Evaluations Failed", stage, env.monitor.fail_assert[stage], env.monitor.num_assert[stage]);
end
while( env.monitor.num_assert.next(stage) );
end
$display(" [TOTAL\t]\t%0d / %0d Evaluations Failed", mon_fail_assert, mon_num_assert);
end

if( passReport && ((env.driver.fail_assert + env.monitor.fail_assert) == 0) )
if( passReport && ((mon_fail_assert + dri_fail_assert) == 0) )
$display("--PASSED--");
else
$display("--FAILED--");
Expand Down

0 comments on commit b2894a1

Please sign in to comment.