blob: 10321f7a4c047793351393ad73b64982b84dc22a [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
`define CALC_NCO(baud_rate, nco_width, clk_freq_khz) \
(baud_rate == BaudRate1p5Mbps && clk_freq_khz == 24_000) ? 16'hffff : \
(longint'(baud_rate) * (2**(nco_width+4))) / (clk_freq_khz * 1000)
class chip_sw_uart_rand_baudrate_vseq extends chip_sw_uart_tx_rx_vseq;
`uvm_object_utils(chip_sw_uart_rand_baudrate_vseq)
`uvm_object_new
localparam NCO_WIDTH = 16;
int uart_clk_freq_khz; // Use khz to avoid fractional value.
rand baud_rate_e baud_rate;
constraint baud_rate_c {
// constrain nco not over nco width
`CALC_NCO(baud_rate, NCO_WIDTH, uart_clk_freq_khz) < (1 << NCO_WIDTH);
// only test 4 other speeds, <= 115k is slow which may take a few hours to complete the test
baud_rate > BaudRate115200;
}
function void pre_randomize();
super.pre_randomize();
if (cfg.chip_clock_source != ChipClockSourceInternal) begin
// Uart bus clock is in div4 domain
uart_clk_freq_khz = cfg.chip_clock_source * 1000 / 4; // div4
if (cfg.chip_clock_source == ChipClockSourceExternal48Mhz) begin
uart_clk_freq_khz = uart_clk_freq_khz * 2; // div2
end
end else begin
// internal uart bus clock is 24Mhz
uart_clk_freq_khz = 24_000;
end
endfunction
function void post_randomize();
super.post_randomize();
cfg.uart_baud_rate = baud_rate;
endfunction
virtual task cpu_init();
// sw_symbol_backdoor_overwrite takes an array as the input
bit [7:0] uart_freq_arr[8] = {<<byte{cfg.uart_baud_rate}};
super.cpu_init();
sw_symbol_backdoor_overwrite("kUartBaudrate", uart_freq_arr);
`uvm_info(`gfn, $sformatf(
"Backdoor_overwrite: configure uart core clk %0d khz, baud_rate: %s",
uart_clk_freq_khz,
baud_rate.name
), UVM_LOW)
if (cfg.chip_clock_source != ChipClockSourceInternal) begin
bit [7:0] use_extclk_arr[] = {cfg.chip_clock_source != ChipClockSourceInternal};
bit [7:0] low_speed_sel_arr[] = {cfg.chip_clock_source == ChipClockSourceExternal48Mhz};
bit [7:0] uart_clk_freq_arr[8] = {<<byte{uart_clk_freq_khz * 1000}};
sw_symbol_backdoor_overwrite("kUseExtClk", use_extclk_arr);
sw_symbol_backdoor_overwrite("kUseLowSpeedSel", low_speed_sel_arr);
sw_symbol_backdoor_overwrite("kClockFreqPeripheralHz", uart_clk_freq_arr);
end
endtask
// When uart starts to send RX data, check if AST is using extclk if extclk is selected.
virtual task send_uart_rx_data(int instance_num, int size = -1, bit random = 0);
if (cfg.chip_clock_source != ChipClockSourceInternal) begin
`DV_CHECK(cfg.ast_ext_clk_vif.is_ext_clk_in_use(),
"expected the external clock to be used for io");
end
super.send_uart_rx_data(instance_num, size, random);
endtask
endclass : chip_sw_uart_rand_baudrate_vseq
`undef CALC_NCO