From f56e4ee12877809bda26a5d31e253d1ac702d126 Mon Sep 17 00:00:00 2001 From: Hugo McNally Date: Tue, 19 Mar 2024 08:42:06 +0000 Subject: [PATCH] Added virtual UART to the verilator simulator --- doc/guide/getting-started.md | 2 +- dv/verilator/sonata_system.cc | 6 ++-- dv/verilator/sonata_system.h | 2 +- dv/verilator/sonata_system_main.cc | 2 +- dv/verilator/sonata_verilator_lint.vlt | 3 ++ dv/verilator/top_verilator.sv | 43 ++++++++++++++++++++++++++ sonata.core | 7 +++-- 7 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 dv/verilator/top_verilator.sv diff --git a/doc/guide/getting-started.md b/doc/guide/getting-started.md index 4f2602a9a..642b0e10c 100644 --- a/doc/guide/getting-started.md +++ b/doc/guide/getting-started.md @@ -74,7 +74,7 @@ fusesoc --cores-root=. run --target=sim --tool=verilator --setup --build lowrisc Running the simulator can be accomplished with the following command, where you can change the `meminit` argument to a different program if you wish: ```sh -./build/lowrisc_sonata_system_0/sim-verilator/Vsonata_system -t --meminit=ram,./sw/cpp/cheri_sanity/boot.elf +./build/lowrisc_sonata_system_0/sim-verilator/Vtop_verilator -t --meminit=ram,./sw/cpp/cheri_sanity/boot.elf ``` I recommend that you make the following change to the sanity check to see quicker changes in simulation: diff --git a/dv/verilator/sonata_system.cc b/dv/verilator/sonata_system.cc index 38b52e282..07f6ebb06 100644 --- a/dv/verilator/sonata_system.cc +++ b/dv/verilator/sonata_system.cc @@ -6,7 +6,7 @@ #include #include -#include "Vsonata_system__Syms.h" +#include "Vtop_verilator__Syms.h" #include "ibex_pcounts.h" #include "sonata_system.h" #include "verilated_toplevel.h" @@ -36,7 +36,7 @@ int SonataSystem::Main(int argc, char **argv) { int SonataSystem::Setup(int argc, char **argv, bool &exit_app) { VerilatorSimCtrl &simctrl = VerilatorSimCtrl::GetInstance(); - simctrl.SetTop(&_top, &_top.clk_sys_i, &_top.rst_sys_ni, + simctrl.SetTop(&_top, &_top.clk_i, &_top.rst_ni, VerilatorSimCtrlFlags::ResetPolarityNegative); _memutil.RegisterMemoryArea("ram", 0x0, &_ram); @@ -66,7 +66,7 @@ bool SonataSystem::Finish() { // Set the scope to the root scope, the ibex_pcount_string function otherwise // doesn't know the scope itself. Could be moved to ibex_pcount_string, but // would require a way to set the scope name from here, similar to MemUtil. - svSetScope(svGetScopeFromName("TOP.sonata_system")); + svSetScope(svGetScopeFromName("TOP.top_verilator.u_sonata_system")); std::cout << "\nPerformance Counters" << std::endl << "====================" << std::endl; diff --git a/dv/verilator/sonata_system.h b/dv/verilator/sonata_system.h index 2b0d148cd..475582032 100644 --- a/dv/verilator/sonata_system.h +++ b/dv/verilator/sonata_system.h @@ -13,7 +13,7 @@ class SonataSystem { protected: - sonata_system _top; + top_verilator _top; VerilatorMemUtil _memutil; MemArea _ram; diff --git a/dv/verilator/sonata_system_main.cc b/dv/verilator/sonata_system_main.cc index b9eb4179c..81284ed0a 100644 --- a/dv/verilator/sonata_system_main.cc +++ b/dv/verilator/sonata_system_main.cc @@ -6,7 +6,7 @@ int main(int argc, char **argv) { SonataSystem sonata_system( - "TOP.sonata_system.u_ram.u_ram.gen_generic.u_impl_generic", + "TOP.top_verilator.u_sonata_system.u_ram.u_ram.gen_generic.u_impl_generic", 1024 * 1024); return sonata_system.Main(argc, argv); diff --git a/dv/verilator/sonata_verilator_lint.vlt b/dv/verilator/sonata_verilator_lint.vlt index 77a8ab371..5ac2a9663 100644 --- a/dv/verilator/sonata_verilator_lint.vlt +++ b/dv/verilator/sonata_verilator_lint.vlt @@ -35,3 +35,6 @@ lint_off -rule WIDTH -file "*ibex_tracer.sv" lint_off -rule WIDTH -file "*ibex_core.sv" lint_off -rule UNDRIVEN -file "*ibexc_top_tracing.sv" + +lint_off -rule WIDTH -file "*uartdpi.sv" +lint_off -rule UNUSED -file "*uartdpi.sv" diff --git a/dv/verilator/top_verilator.sv b/dv/verilator/top_verilator.sv new file mode 100644 index 000000000..c1c3508c9 --- /dev/null +++ b/dv/verilator/top_verilator.sv @@ -0,0 +1,43 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This is the top level that connects the system to the virtual devices. +module top_verilator (input logic clk_i, rst_ni); + + localparam ClockFrequency = 50_000_000; + localparam BaudRate = 115_200; + + logic uart_sys_rx, uart_sys_tx; + + // Instantiating the Sonata System. + sonata_system u_sonata_system ( + // Clock and Reset + .clk_sys_i (clk_i), + .rst_sys_ni(rst_ni), + + // UART TX and RX + .uart_rx_i (uart_sys_rx), + .uart_tx_o (uart_sys_tx), + + // Remaining IO + .gp_i (0), + .gp_o ( ), + .pwm_o ( ), + .spi_rx_i (0), + .spi_tx_o ( ), + .spi_sck_o ( ) + ); + + // Virtual UART + uartdpi #( + .BAUD(BaudRate), + .FREQ(ClockFrequency) + ) u_uartdpi ( + .clk_i, + .rst_ni, + .active (1'b1 ), + .tx_o (uart_sys_rx), + .rx_i (uart_sys_tx) + ); +endmodule diff --git a/sonata.core b/sonata.core index 6faaf921c..677071216 100644 --- a/sonata.core +++ b/sonata.core @@ -33,7 +33,10 @@ filesets: - lowrisc:dv_verilator:memutil_verilator - lowrisc:dv_verilator:simutil_verilator - lowrisc:dv_verilator:ibex_pcounts + - lowrisc:dv_dpi_c:uartdpi:0.1 + - lowrisc:dv_dpi_sv:uartdpi:0.1 files: + - dv/verilator/top_verilator.sv: { file_type: systemVerilogSource } - dv/verilator/sonata_system.cc: { file_type: cppSource } - dv/verilator/sonata_system.h: { file_type: cppSource, is_include_file: true} - dv/verilator/sonata_system_main.cc: { file_type: cppSource } @@ -106,7 +109,7 @@ targets: default_tool: verilator filesets_append: - files_verilator - toplevel: sonata_system + toplevel: top_verilator tools: verilator: mode: cc @@ -118,7 +121,7 @@ targets: - '--trace-structs' - '--trace-params' - '--trace-max-array 1024' - - '-CFLAGS "-std=c++11 -Wall -DVM_TRACE_FMT_FST -DTOPLEVEL_NAME=sonata_system"' + - '-CFLAGS "-std=c++11 -Wall -DVM_TRACE_FMT_FST -DTOPLEVEL_NAME=top_verilator"' - '-LDFLAGS "-pthread -lutil -lelf"' - "-Wall" - "-Wwarn-IMPERFECTSCH"