`default_nettype none `timescale 1ns/1ns `include "messages.vh" `ifndef SIMULATION `error_SIMULATION_not_defined ; /* Cause syntax error */ `endif `define MAX_WORD_IDX 1280 /* * Using model from models/master.v would require an operations file over 1280 * lines long, so we'll write a custom master instead. */ module simple_master ( input wire ACK_I, input wire CLK_I, output wire [19:0] ADR_O, input wire [15:0] DAT_I, output wire [15:0] DAT_O, input wire RST_I, output wire STB_O, output wire CYC_O, output wire WE_O, input wire STALL_I, /* Non-wishbone */ output wire finished ); integer commands_sent; integer commands_acknowledged; wire sent; wire acknowledged; assign sent = !STALL_I && STB_O; assign acknowledged = ((commands_acknowledged == commands_sent && STB_O && !STALL_I) || commands_acknowledged < commands_sent) && ACK_I; wire sent_all; wire acknowledged_all; assign sent_all = commands_sent == `MAX_WORD_IDX + 1 || (commands_sent == `MAX_WORD_IDX && sent); assign acknowledged_all = commands_acknowledged == `MAX_WORD_IDX + 1 || (commands_acknowledged == `MAX_WORD_IDX && acknowledged); assign finished = acknowledged_all; reg sending; assign STB_O = sending; assign WE_O = sending; assign CYC_O = !acknowledged_all && !RST_I; assign ADR_O = commands_sent; assign DAT_O = commands_sent == `MAX_WORD_IDX ? 1 : {commands_sent[6:0], 1'b1, commands_sent[6:0], 1'b0}; initial begin commands_sent <= 0; commands_acknowledged <= 0; end always @ (posedge CLK_I) begin if (RST_I) begin sending <= 0; commands_sent <= 0; commands_acknowledged <= 0; end else begin if (sent) commands_sent <= commands_sent + 1; if (acknowledged) commands_acknowledged <= commands_acknowledged + 1; if (sent_all) sending <= 0; else sending <= 1; end // else: !if(RST_I) end // always @ (posedge CLK_I) endmodule // simple_master module vga_test #( /* wishbone clock isn't in any special way related to clock_25mhz */ parameter WISHBONE_CLOCK_PERIOD = 14 /* ns */ ) (); wire M_ACK_I; wire M_CLK_I; wire [19:0] M_ADR_O; wire [15:0] M_DAT_I; wire [15:0] M_DAT_O; wire M_RST_I; wire M_STB_O; wire M_CYC_O; wire M_WE_O; wire M_STALL_I; wire S_ACK_O; wire S_CLK_I; wire [10:0] S_ADR_I; wire [15:0] S_DAT_I; wire [15:0] S_DAT_O; wire S_RST_I; wire S_STB_I; wire S_WE_I; wire S_STALL_O; /* Non-wishbone */ wire M_finished; reg clock_25mhz; wire vga_h_sync; wire vga_v_sync; wire [2:0] vga_red; wire [2:0] vga_green; wire [2:0] vga_blue; wire [9:0] image_writes; simple_master master ( .ACK_I(M_ACK_I), .CLK_I(M_CLK_I), .ADR_O(M_ADR_O), .DAT_I(M_DAT_I), .DAT_O(M_DAT_O), .RST_I(M_RST_I), .STB_O(M_STB_O), .CYC_O(M_CYC_O), .WE_O(M_WE_O), .STALL_I(M_STALL_I), .finished(M_finished) ); vga #( .FONT_FILE("../../design/font.mem") ) vga_controller ( .ACK_O(S_ACK_O), .CLK_I(S_CLK_I), .ADR_I(S_ADR_I), .DAT_I(S_DAT_I), .DAT_O(S_DAT_O), .RST_I(S_RST_I), .STB_I(S_STB_I), .WE_I(S_WE_I), .STALL_O(S_STALL_O), /* Non-wishbone */ .clock_25mhz(clock_25mhz), .h_sync(vga_h_sync), .v_sync(vga_v_sync), .red(vga_red), .green(vga_green), .blue(vga_blue) ); VGA_640_480_60Hz vga_display ( .horizontal_sync(vga_h_sync), .vertical_sync(vga_v_sync), .red(vga_red), .green(vga_green), .blue(vga_blue), .image_writes(image_writes) ); reg CLK; reg RST; assign M_ACK_I = S_ACK_O; assign M_CLK_I = CLK; assign M_DAT_I = S_DAT_O; assign M_RST_I = RST; assign M_STALL_I = S_STALL_O; assign S_CLK_I = CLK; assign S_ADR_I = M_ADR_O[10:0]; /* Ignore 9 topmost bits */ assign S_DAT_I = M_DAT_O; assign S_RST_I = RST; assign S_STB_I = M_STB_O && M_CYC_O; assign S_WE_I = M_WE_O; initial begin CLK <= 0; RST <= 1; while (1) begin #(WISHBONE_CLOCK_PERIOD / 2); CLK <= ~CLK; if (CLK) RST <= 0; end end // initial begin initial begin clock_25mhz <= 0; while (1) begin #20; clock_25mhz <= ~clock_25mhz; end end always @ (image_writes) begin if (image_writes > 0) begin if (!M_finished) $display("error: master hasn't finished its operations"); $finish; end end parameter SCREEN_DISPLAY_TIME = 10 ** 9 / 60; /* 60 screens per second */ parameter MAX_SIM_TIME = `MAX_WORD_IDX * WISHBONE_CLOCK_PERIOD + SCREEN_DISPLAY_TIME + 1000; /* Some safety margin */ initial begin #MAX_SIM_TIME; if (!M_finished) begin $display("error: master hasn't finished its operations in %0d ns", MAX_SIM_TIME); end if (image_writes == 0) $display("error: no VGA image displayed in %0d ns", MAX_SIM_TIME); $finish; end // initial begin endmodule // vga_test