Hi,
I am trying to create a UVM driver logic to an interface which is very similar to an APB Interface.
In the run_phase of the driver, I have created simple tasks ‘send_write_tx’ and ‘send_read_tx’ which drives the respective write and read transactions over the Interface :
Interface Code :
interface proc_interface #(int DSIZE = 32) (input clk, input rst);
logic valid;
logic ready;
logic wr_rd;
logic [2:0] addr;
logic [DSIZE-1:0] wr_data;
logic [DSIZE-1:0] rd_data;
// Clocking block
clocking cb @(posedge clk);
output valid;
input ready;
output wr_rd;
output addr;
output wr_data;
input rd_data;
endclocking
endinterface
Driver Code Logic :
// Run Phase
task run_phase(uvm_phase phase);
tx_typ proc_seq_item;
forever
begin
// Wait for reset being deasserted
wait(proc_vif.rst == 1'b0);
seq_item_port.get_next_item(proc_seq_item);
if(proc_seq_item.wr_rd == 1'b1)
begin send_write_tx(proc_seq_item); end
else
begin send_read_tx(proc_seq_item); end
seq_item_port.item_done();
end
endtask
// Task for Sending Write
task send_write_tx(tx_typ tx);
`uvm_info(report_id,"Sending Write Transaction", UVM_LOW)
tx.print();
wait(proc_vif.ready);
@(posedge proc_vif.clk)
begin
proc_vif.wr_rd <= tx.wr_rd;
proc_vif.valid <= 1'b1;
proc_vif.wr_data <= tx.wr_data;
proc_vif.addr <= tx.addr;
end
endtask
// Task for Sending Read
task send_read_tx(tx_typ tx);
wait(proc_vif.ready);
@(posedge proc_vif.clk)
begin
proc_vif.wr_rd <= tx.wr_rd;
proc_vif.valid <= 1'b1;
tx.rd_data <= proc_vif.rd_data;
proc_vif.addr <= tx.addr;
end
endtask
With the above said implementation, what is the correct way to de-assert the ‘valid’ after a transaction is complete ?.
My point being, that if ‘valid’ is de-asserted, the de-assertion will consume 1 clock.
But this compromised clock could have been another valid transaction (Read or Write), i.e. what if another transaction was in pipeline ?.
Also if left unhandled (i.e. left asserted), the next clock will assume the transaction as still valid, since ‘valid’ remains asserted.
Thanks
Jayant