| // Copyright 2017 Embecosm Limited <www.embecosm.com> |
| // Copyright 2018 Robert Balas <balasr@student.ethz.ch> |
| // Copyright 2020 ETH Zurich and University of Bologna. |
| // Copyright and related rights are licensed under the Solderpad Hardware |
| // License, Version 0.51 (the "License"); you may not use this file except in |
| // compliance with the License. You may obtain a copy of the License at |
| // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law |
| // or agreed to in writing, software, hardware and materials distributed under |
| // this 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. |
| |
| // Top level wrapper for a RI5CY testbench |
| // Contributor: Robert Balas <balasr@iis.ee.ethz.ch> |
| // Jeremy Bennett <jeremy.bennett@embecosm.com> |
| |
| module tb_top #( |
| parameter int unsigned INSTR_RDATA_WIDTH = 32, |
| parameter int unsigned RAM_ADDR_WIDTH = 22, |
| parameter logic [31:0] BOOT_ADDR = 'h1A00_0180, |
| parameter bit JTAG_BOOT = 1, |
| parameter int unsigned OPENOCD_PORT = 9999 |
| ); |
| |
| // comment to record execution trace |
| //`define TRACE_EXECUTION |
| |
| const time CLK_PHASE_HI = 5ns; |
| const time CLK_PHASE_LO = 5ns; |
| const time CLK_PERIOD = CLK_PHASE_HI + CLK_PHASE_LO; |
| const time STIM_APPLICATION_DEL = CLK_PERIOD * 0.1; |
| const time RESP_ACQUISITION_DEL = CLK_PERIOD * 0.9; |
| const time RESET_DEL = STIM_APPLICATION_DEL; |
| const int RESET_WAIT_CYCLES = 4; |
| |
| // clock and reset for tb |
| logic clk = 'b1; |
| logic rst_n = 'b0; |
| |
| // testbench result |
| logic tests_passed; |
| logic tests_failed; |
| |
| // signals for ri5cy |
| logic fetch_enable; |
| |
| |
| // make the core start fetching instruction immediately |
| assign fetch_enable = '1; |
| |
| // allow vcd dump |
| initial begin: dump_vars |
| if ($test$plusargs("vcd")) begin |
| $dumpfile("riscy_tb.vcd"); |
| $dumpvars(0, tb_top); |
| end |
| `ifdef QUESTA |
| if ($test$plusargs("wlfdump")) begin |
| $wlfdumpvars(0, tb_top); |
| end |
| `endif |
| end |
| |
| // we either load the provided firmware or execute a small test program that |
| // doesn't do more than an infinite loop with some I/O |
| initial begin: load_prog |
| automatic logic [1023:0] firmware; |
| automatic int prog_size = 6; |
| |
| if($value$plusargs("firmware=%s", firmware)) begin |
| if($test$plusargs("verbose")) |
| $display("[TESTBENCH] %t: loading firmware %0s ...", |
| $time, firmware); |
| $readmemh(firmware, tb_test_env_i.mm_ram_i.dp_ram_i.mem); |
| |
| end else begin |
| $display("No firmware specified"); |
| end |
| end |
| |
| // clock generation |
| initial begin: clock_gen |
| forever begin |
| #CLK_PHASE_HI clk = 1'b0; |
| #CLK_PHASE_LO clk = 1'b1; |
| end |
| end: clock_gen |
| |
| // reset generation |
| initial begin: reset_gen |
| rst_n = 1'b0; |
| |
| // wait a few cycles |
| repeat (RESET_WAIT_CYCLES) begin |
| @(posedge clk); //TODO: was posedge, see below |
| end |
| |
| // start running |
| #RESET_DEL rst_n = 1'b1; |
| if($test$plusargs("verbose")) |
| $display("reset deasserted", $time); |
| |
| end: reset_gen |
| |
| // set timing format |
| initial begin: timing_format |
| $timeformat(-9, 0, "ns", 9); |
| end: timing_format |
| |
| // check if we succeded |
| always_ff @(posedge clk, negedge rst_n) begin |
| if (tests_passed) begin |
| $display("Exit Success"); |
| $finish; |
| end |
| if (tests_failed) begin |
| $display("Exit FAILURE"); |
| $finish; |
| end |
| end |
| |
| // wrapper for riscv, the memory system and stdout peripheral |
| tb_test_env #( |
| .INSTR_RDATA_WIDTH (INSTR_RDATA_WIDTH), |
| .RAM_ADDR_WIDTH (RAM_ADDR_WIDTH), |
| .BOOT_ADDR (BOOT_ADDR), |
| .JTAG_BOOT (JTAG_BOOT), |
| .OPENOCD_PORT (OPENOCD_PORT) |
| ) tb_test_env_i( |
| .clk_i ( clk ), |
| .rst_ni ( rst_n ), |
| .fetch_enable_i ( fetch_enable ), |
| .tests_passed_o ( tests_passed ), |
| .tests_failed_o ( tests_failed ) |
| ); |
| |
| endmodule // tb_top |