diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 739221a6..82a7c20b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -95,6 +95,11 @@ jobs: fi displayName: Lint Verilog source files with Verilator + - bash: | + # Build and run CSR testbench + fusesoc --cores-root=. run --target=sim --tool=verilator lowrisc:ibex:tb_cs_registers + displayName: Build and run CSR testbench with Verilator + - bash: | cd build git clone https://github.com/riscv/riscv-compliance.git diff --git a/dv/cs_registers/env/env_dpi.cc b/dv/cs_registers/env/env_dpi.cc index 7d21df9e..0227cf51 100644 --- a/dv/cs_registers/env/env_dpi.cc +++ b/dv/cs_registers/env/env_dpi.cc @@ -35,7 +35,10 @@ void env_final() { delete reg_env; } -void env_tick(svBit *stop_req) { reg_env->GetStopReq(stop_req); } +void env_tick(svBit *stop_req, svBit *test_passed) { + reg_env->GetStopReq(stop_req); + reg_env->GetTestPass(test_passed); +} #ifdef __cplusplus } diff --git a/dv/cs_registers/env/env_dpi.sv b/dv/cs_registers/env/env_dpi.sv index 4f23aba2..626c9894 100644 --- a/dv/cs_registers/env/env_dpi.sv +++ b/dv/cs_registers/env/env_dpi.sv @@ -15,7 +15,8 @@ package env_dpi; import "DPI-C" function void env_tick( - output bit stop_req); + output bit stop_req, + output bit test_passed); endpackage diff --git a/dv/cs_registers/env/register_environment.cc b/dv/cs_registers/env/register_environment.cc index 8e25f893..a7a41694 100644 --- a/dv/cs_registers/env/register_environment.cc +++ b/dv/cs_registers/env/register_environment.cc @@ -29,3 +29,7 @@ void RegisterEnvironment::OnFinal() { void RegisterEnvironment::GetStopReq(unsigned char *stop_req) { *stop_req = simctrl_->StopRequested(); } + +void RegisterEnvironment::GetTestPass(unsigned char *test_passed) { + *test_passed = simctrl_->TestPassed(); +} diff --git a/dv/cs_registers/env/register_environment.h b/dv/cs_registers/env/register_environment.h index 3350081a..e0a7b7a3 100644 --- a/dv/cs_registers/env/register_environment.h +++ b/dv/cs_registers/env/register_environment.h @@ -23,6 +23,8 @@ class RegisterEnvironment { void GetStopReq(unsigned char *stop_req); + void GetTestPass(unsigned char *test_passed); + private: CSRParams params_; SimCtrl *simctrl_; diff --git a/dv/cs_registers/env/simctrl.cc b/dv/cs_registers/env/simctrl.cc index 253fbfb3..1923152d 100644 --- a/dv/cs_registers/env/simctrl.cc +++ b/dv/cs_registers/env/simctrl.cc @@ -15,6 +15,8 @@ void SimCtrl::RequestStop(bool success) { bool SimCtrl::StopRequested() { return stop_requested_; } +bool SimCtrl::TestPassed() { return success_; } + void SimCtrl::OnFinal() { std::cout << std::endl << "//-------------//" << std::endl diff --git a/dv/cs_registers/env/simctrl.h b/dv/cs_registers/env/simctrl.h index b7848814..db5b76c7 100644 --- a/dv/cs_registers/env/simctrl.h +++ b/dv/cs_registers/env/simctrl.h @@ -10,6 +10,7 @@ class SimCtrl { SimCtrl(); void RequestStop(bool success); bool StopRequested(); + bool TestPassed(); void OnFinal(); private: diff --git a/dv/cs_registers/tb/tb_cs_registers.cc b/dv/cs_registers/tb/tb_cs_registers.cc index 4d73c741..ed0b3cb3 100644 --- a/dv/cs_registers/tb/tb_cs_registers.cc +++ b/dv/cs_registers/tb/tb_cs_registers.cc @@ -18,5 +18,12 @@ int main(int argc, char **argv) { simctrl.SetTop(&top, &top.clk_i, &top.in_rst_ni, VerilatorSimCtrlFlags::ResetPolarityNegative); - return simctrl.Exec(argc, argv); + + // Get pass / fail from Verilator + int retcode = simctrl.Exec(argc, argv); + if (!retcode) { + // Get pass / fail from testbench + retcode = !top.test_passed_o; + } + return retcode; } diff --git a/dv/cs_registers/tb/tb_cs_registers.sv b/dv/cs_registers/tb/tb_cs_registers.sv index c6984e3e..a190dfd7 100644 --- a/dv/cs_registers/tb/tb_cs_registers.sv +++ b/dv/cs_registers/tb/tb_cs_registers.sv @@ -13,7 +13,8 @@ module tb_cs_registers #( ) ( // Clock and Reset inout wire clk_i, - inout wire in_rst_ni + inout wire in_rst_ni, + output wire test_passed_o ); logic dpi_rst_ni; @@ -126,6 +127,7 @@ module tb_cs_registers #( // DPI calls bit stop_simulation; + bit test_passed; bit [31:0] seed; initial begin @@ -140,13 +142,17 @@ module tb_cs_registers #( end always_ff @(posedge clk_i) begin - env_dpi::env_tick(stop_simulation); + env_dpi::env_tick(stop_simulation, test_passed); rst_dpi::rst_tick("rstn_driver", dpi_rst_ni); if (stop_simulation) begin $finish(); end end + // Signal test pass / fail as an output (Verilator sims can pick this up and use it as a + // return code) + assign test_passed_o = test_passed; + always_ff @(posedge clk_i or negedge rst_ni) begin reg_dpi::monitor_tick("reg_driver", rst_ni,