blob: f1f0397d55b62f11e6ac7ec46d485e3d595f77a8 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
class uart_driver extends dv_base_driver #(uart_item, uart_agent_cfg);
`uvm_component_utils(uart_driver)
`uvm_component_new
task run_phase(uvm_phase phase);
reset_signals();
get_and_drive();
endtask
// Resets signals.
virtual task reset_signals();
cfg.vif.reset_uart_rx();
endtask
// Sets the value of rx after randomly glitching for 10% of uart clk
task set_rx(input bit val);
uint glitch_ns = uint'(cfg.vif.uart_clk_period_ns * cfg.get_uart_period_glitch_pct() / 100);
repeat (glitch_ns) begin
if (!cfg.under_reset) begin
cfg.vif.uart_rx <= $urandom_range(0, 1);
#1ns;
end
end
cfg.vif.uart_rx <= val;
endtask
// Drives transfers.
virtual task get_and_drive();
bit send_data[];
forever begin
seq_item_port.get(req);
$cast(rsp, req.clone());
rsp.set_id_info(req);
if (!cfg.under_reset) begin
`uvm_info(`gfn, $sformatf("starting to send rx item: %0s", rsp.sprint()), UVM_HIGH)
// we send parity if enabled or if overridden in the req
if (cfg.en_parity ^ req.ovrd_en_parity) begin
send_data = new[NUM_UART_XFER_BITS_WO_PARITY + 1]; // + 1 for parity bit
{<<{send_data}} = {req.stop_bit, req.parity, req.data, req.start_bit};
end
else begin
send_data = new[NUM_UART_XFER_BITS_WO_PARITY];
{<<{send_data}} = {req.stop_bit, req.data, req.start_bit};
end
// send data on uart_rx
for (int i = 0; i < send_data.size(); i++) begin
set_rx(send_data[i]);
wait_uart_rx_cycle();
end
`uvm_info(`gfn, $sformatf("finished sending rx item: %0s", rsp.sprint()), UVM_HIGH)
end
if (cfg.under_reset) begin // under_reset
`uvm_info(`gfn, $sformatf("Reset happens and drop rx item: %0s", rsp.sprint()), UVM_HIGH)
end
seq_item_port.put_response(rsp);
end
endtask
virtual task wait_uart_rx_cycle();
fork
begin : isolation_fork
fork
begin
wait(cfg.under_reset);
end
begin
@(cfg.vif.drv_rx_mp.drv_rx_cb);
end
join_any
disable fork;
end : isolation_fork
join
endtask
endclass