/* testbench.v - Testbench for the 9086 CPU This file is part of the 9086 project. Copyright (c) 2023 Efthymios Kritikos This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /*In hz */ `define CPU_SPEED 1000 module tb; wire clock; reg reset; reg clk_enable; wire [19:0]address_bus; wire [15:0]data_bus; wire rd,wr,HALT; wire [2:0] ERROR; wire IOMEM; system system( .clock(clock), .reset(reset), .address_bus(address_bus), .data_bus(data_bus), .rd(rd), .wr(wr), .HALT(HALT), .ERROR(ERROR), .IOMEM(IOMEM) ); clock_gen #(.FREQ(1000)) u1(clk_enable, clock); string memdump_name; initial begin clk_enable = 1; do_reset = 0; end reg [1:0]do_reset; always @(posedge clock) begin case(do_reset) 2'd0:begin do_reset<=1; end 2'd1:begin do_reset<=2; reset <= 0; end 2'd2:begin do_reset<=3; reset <= 1; end 2'd3:begin end endcase end endmodule /*Clock generator*/ module clock_gen (input enable, output reg clk); parameter FREQ = 1000; // in HZ parameter PHASE = 0; // in degrees parameter DUTY = 50; // in percentage real clk_pd = 1.0/FREQ * 1000000000; // convert to ms real clk_on = DUTY/100.0 * clk_pd; real clk_off = (100.0 - DUTY)/100.0 * clk_pd; real quarter = clk_pd/4; real start_dly = quarter * PHASE/90; reg start_clk; initial begin end // Initialise variables to zero initial begin clk = 0; start_clk = 0; end // When clock is enabled, delay driving the clock to one in order // to achieve the phase effect. start_dly is configured to the // correct delay for the configured phase. When enable is 0, // allow enough time to complete the current clock period always @ (posedge enable or negedge enable) begin if (enable) begin #(start_dly) start_clk = 1; end else begin #(start_dly) start_clk = 0; end end // Achieve duty cycle by a skewed clock on/off time and let this // run as long as the clocks are turned on. always @(posedge start_clk) begin if (start_clk) begin clk = 1; while (start_clk) begin #(clk_on) clk = 0; #(clk_off) clk = 1; end clk = 0; end end endmodule