[sw/device] Add kUartTxFifoCpuCycles

This change adds `kUartTxFifoCpuCycles` that gives the time it takes to
transmit the entire UART TX FIFO in CPU cycles.

Signed-off-by: Alphan Ulusoy <alphan@google.com>
diff --git a/sw/device/lib/arch/device.h b/sw/device/lib/arch/device.h
index 33c5669..81b0da9 100644
--- a/sw/device/lib/arch/device.h
+++ b/sw/device/lib/arch/device.h
@@ -107,6 +107,21 @@
 extern const uint32_t kUartNCOValue;
 
 /**
+ * Helper macro to calculate the time it takes to transmit the entire UART TX
+ * FIFO in CPU cycles.
+ *
+ * This macro assumes 10 bits per byte (no parity bits) and a 32 byte deep TX
+ * FIFO.
+ */
+#define CALCULATE_UART_TX_FIFO_CPU_CYCLES(baud_rate_, cpu_freq_) \
+  ((cpu_freq_)*10 * 32 / (baud_rate_))
+
+/**
+ * The time it takes to transmit the entire UART TX fifo in CPU cycles.
+ */
+extern const uint32_t kUartTxFifoCpuCycles;
+
+/**
  * An address to write to to report test status.
  *
  * If this is zero, there is no address to write to to report test status.
diff --git a/sw/device/lib/arch/device_fpga_cw310.c b/sw/device/lib/arch/device_fpga_cw310.c
index 7b8b002..21a9b12 100644
--- a/sw/device/lib/arch/device_fpga_cw310.c
+++ b/sw/device/lib/arch/device_fpga_cw310.c
@@ -24,6 +24,9 @@
 const uint32_t kUartNCOValue =
     CALCULATE_UART_NCO(kUartBaudrate, kClockFreqPeripheralHz);
 
+const uint32_t kUartTxFifoCpuCycles =
+    CALCULATE_UART_TX_FIFO_CPU_CYCLES(kUartBaudrate, kClockFreqCpuHz);
+
 const uintptr_t kDeviceTestStatusAddress = 0;
 
 const uintptr_t kDeviceLogBypassUartAddress = 0;
diff --git a/sw/device/lib/arch/device_fpga_nexysvideo.c b/sw/device/lib/arch/device_fpga_nexysvideo.c
index 0f7647f..3e8366d 100644
--- a/sw/device/lib/arch/device_fpga_nexysvideo.c
+++ b/sw/device/lib/arch/device_fpga_nexysvideo.c
@@ -24,6 +24,9 @@
 const uint32_t kUartNCOValue =
     CALCULATE_UART_NCO(kUartBaudrate, kClockFreqPeripheralHz);
 
+const uint32_t kUartTxFifoCpuCycles =
+    CALCULATE_UART_TX_FIFO_CPU_CYCLES(kUartBaudrate, kClockFreqCpuHz);
+
 const uintptr_t kDeviceTestStatusAddress = 0;
 
 const uintptr_t kDeviceLogBypassUartAddress = 0;
diff --git a/sw/device/lib/arch/device_sim_dv.c b/sw/device/lib/arch/device_sim_dv.c
index 2426550..a3ba855 100644
--- a/sw/device/lib/arch/device_sim_dv.c
+++ b/sw/device/lib/arch/device_sim_dv.c
@@ -26,6 +26,9 @@
 const uint32_t kUartNCOValue =
     CALCULATE_UART_NCO(kUartBaudrate, kClockFreqPeripheralHz);
 
+const uint32_t kUartTxFifoCpuCycles =
+    CALCULATE_UART_TX_FIFO_CPU_CYCLES(kUartBaudrate, kClockFreqCpuHz);
+
 // Defined in `hw/top_earlgrey/dv/env/chip_env_pkg.sv`
 const uintptr_t kDeviceTestStatusAddress = 0x30000000;
 
diff --git a/sw/device/lib/arch/device_sim_verilator.c b/sw/device/lib/arch/device_sim_verilator.c
index a43db9d..db59d7f 100644
--- a/sw/device/lib/arch/device_sim_verilator.c
+++ b/sw/device/lib/arch/device_sim_verilator.c
@@ -27,6 +27,9 @@
 const uint32_t kUartNCOValue =
     CALCULATE_UART_NCO(kUartBaudrate, kClockFreqPeripheralHz);
 
+const uint32_t kUartTxFifoCpuCycles =
+    CALCULATE_UART_TX_FIFO_CPU_CYCLES(kUartBaudrate, kClockFreqCpuHz);
+
 // Defined in `hw/top_earlgrey/chip_earlgrey_verilator.core`
 const uintptr_t kDeviceTestStatusAddress = 0x30000000;