blob: 2beb1c9da5bfc3960fd3abaee7aa70141a2bee9a [file] [log] [blame]
// Copyright 2024 Google LLC
// Copyright lowRISC contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include "verilated_toplevel.h"
#include "verilator_memutil.h"
#include "verilator_sim_ctrl.h"
int main(int argc, char **argv) {
sencha_sim_tb top;
VerilatorMemUtil memutil;
VerilatorSimCtrl &simctrl = VerilatorSimCtrl::GetInstance();
simctrl.SetTop(&top, &top.clk_i, &top.rst_ni,
VerilatorSimCtrlFlags::ResetPolarityNegative);
std::string top_scope("TOP.sencha_sim_tb.u_dut.top_sencha");
std::string ram1p_adv_scope(
"u_prim_ram_1p_adv.u_mem."
"gen_generic.u_impl_generic");
MemArea rom(top_scope + (".u_rom_ctrl.gen_rom_scramble_enabled.u_rom.u_rom."
"u_prim_rom.gen_generic.u_impl_generic"),
0x4000 / 4, 4);
MemArea ram(top_scope + ".u_ram1p_ram_main." + ram1p_adv_scope, 0x20000 / 4,
4);
// Only handle the lower bank of flash for now.
MemArea flash(top_scope +
".u_flash_ctrl.u_eflash.u_flash.gen_generic.u_impl_generic."
"gen_prim_flash_banks[0].u_prim_flash_bank.u_mem."
"gen_generic.u_impl_generic",
0x80000 / 8, 8);
// Start with the flash region erased. Future loads can overwrite.
std::vector<uint8_t> all_ones(flash.GetSizeBytes());
std::fill(all_ones.begin(), all_ones.end(), 0xffu);
flash.Write(/*word_offset=*/0, all_ones);
MemArea otp(top_scope + ".u_otp_ctrl.u_otp.gen_generic.u_impl_generic." +
ram1p_adv_scope,
0x4000 / 4, 4);
MemArea ram_smc(top_scope + ".u_ram1p_ram_smc.u_mem.gen_generic.u_impl_generic",
0x400000 / 4, 4);
MemArea ml_dmem(top_scope + ".u_ml_top.u_ml_dmem.u_ram1p_dmem.u_mem.gen_generic.u_impl_generic",
0x400000 / 32, 32);
memutil.RegisterMemoryArea("rom", 0x8000, &rom);
memutil.RegisterMemoryArea("ram", 0x10000000u, &ram);
memutil.RegisterMemoryArea("flash", 0x20000000u, &flash);
memutil.RegisterMemoryArea("otp", 0x40000000u /* (bogus LMA) */, &otp);
memutil.RegisterMemoryArea("ram_smc", 0x50000000u, &ram_smc);
memutil.RegisterMemoryArea("ml_dmem", 0x5A000000u, &ml_dmem);
simctrl.RegisterExtension(&memutil);
// The initial reset delay must be long enough such that pwr/rst/clkmgr will
// release clocks to the entire design. This allows for synchronous resets
// to appropriately propagate.
// The reset duration must be appropriately sized to the divider for clk_aon
// in chip_sencha_verilator.sv. It must be at least 2 cycles of clk_aon.
simctrl.SetInitialResetDelay(20000);
simctrl.SetResetDuration(10);
std::cout << "Simulation of Shodan Sencha" << std::endl
<< "=================================" << std::endl
<< std::endl;
return simctrl.Exec(argc, argv).first;
}