From 1d1217609e552fd01be9df20cc8d77e25c5a8bdc Mon Sep 17 00:00:00 2001 From: Jens True Date: Tue, 20 Nov 2018 17:22:49 +0100 Subject: [PATCH] Added AXI interface --- minized_vga.xdc | 23 ++- simplevga_v1_0.v | 111 +++++++++++ simplevga_v1_0_S00_AXI.v | 409 +++++++++++++++++++++++++++++++++++++++ userland.c | 11 ++ vga640x480.v | 24 ++- vgasquare.v | 5 +- 6 files changed, 558 insertions(+), 25 deletions(-) create mode 100644 simplevga_v1_0.v create mode 100644 simplevga_v1_0_S00_AXI.v create mode 100644 userland.c diff --git a/minized_vga.xdc b/minized_vga.xdc index 6957622..6de71c2 100644 --- a/minized_vga.xdc +++ b/minized_vga.xdc @@ -3,17 +3,20 @@ ####################################################################### -set_property PACKAGE_PIN L15 [get_ports {PL_VGA_R[0]}] -set_property IOSTANDARD LVCMOS33 [get_ports {PL_VGA_R[0]}] +set_property PACKAGE_PIN L15 [get_ports {PL_VGA_R}] +set_property IOSTANDARD LVCMOS33 [get_ports {PL_VGA_R}] -set_property PACKAGE_PIN M15 [get_ports {PL_VGA_G[0]}] -set_property IOSTANDARD LVCMOS33 [get_ports {PL_VGA_G[0]}] +set_property PACKAGE_PIN M15 [get_ports {PL_VGA_G}] +set_property IOSTANDARD LVCMOS33 [get_ports {PL_VGA_G}] -set_property PACKAGE_PIN L14 [get_ports {PL_VGA_B[0]}] -set_property IOSTANDARD LVCMOS33 [get_ports {PL_VGA_B[0]}] +set_property PACKAGE_PIN L14 [get_ports {PL_VGA_B}] +set_property IOSTANDARD LVCMOS33 [get_ports {PL_VGA_B}] -set_property PACKAGE_PIN K13 [get_ports {PL_VGA_HSYNC[0]}] -set_property IOSTANDARD LVCMOS33 [get_ports {PL_VGA_HSYNC[0]}] +set_property PACKAGE_PIN K13 [get_ports {PL_VGA_HS}] +set_property IOSTANDARD LVCMOS33 [get_ports {PL_VGA_HS}] -set_property PACKAGE_PIN L13 [get_ports {PL_VGA_VSYNC[0]}] -set_property IOSTANDARD LVCMOS33 [get_ports {PL_VGA_VSYNC[0]}] \ No newline at end of file +set_property PACKAGE_PIN L13 [get_ports {PL_VGA_VS}] +set_property IOSTANDARD LVCMOS33 [get_ports {PL_VGA_VS}] + +set_property PACKAGE_PIN N13 [get_ports {PL_VGA_ACTIVE}] +set_property IOSTANDARD LVCMOS33 [get_ports {PL_VGA_ACTIVE}] \ No newline at end of file diff --git a/simplevga_v1_0.v b/simplevga_v1_0.v new file mode 100644 index 0000000..1d7c98f --- /dev/null +++ b/simplevga_v1_0.v @@ -0,0 +1,111 @@ + +`timescale 1 ns / 1 ps + + module simplevga_v1_0 # + ( + // Users to add parameters here + + // User parameters ends + // Do not modify the parameters beyond this line + + + // Parameters of Axi Slave Bus Interface S00_AXI + parameter integer C_S00_AXI_DATA_WIDTH = 32, + parameter integer C_S00_AXI_ADDR_WIDTH = 4 + ) + ( + // Users to add ports here + input wire I_PIXEL_CLK, + output wire O_VGA_ACTIVE, //High when drawing is active + output wire O_VGA_HS, // horizontal sync output + output wire O_VGA_VS, // vertical sync output + output wire O_VGA_R, // 1-bit VGA red output + output wire O_VGA_G, // 1-bit VGA green output + output wire O_VGA_B, // 1-bit VGA blue output + // User ports ends + // Do not modify the ports beyond this line + + + // Ports of Axi Slave Bus Interface S00_AXI + input wire s00_axi_aclk, + input wire s00_axi_aresetn, + input wire [C_S00_AXI_ADDR_WIDTH-1 : 0] s00_axi_awaddr, + input wire [2 : 0] s00_axi_awprot, + input wire s00_axi_awvalid, + output wire s00_axi_awready, + input wire [C_S00_AXI_DATA_WIDTH-1 : 0] s00_axi_wdata, + input wire [(C_S00_AXI_DATA_WIDTH/8)-1 : 0] s00_axi_wstrb, + input wire s00_axi_wvalid, + output wire s00_axi_wready, + output wire [1 : 0] s00_axi_bresp, + output wire s00_axi_bvalid, + input wire s00_axi_bready, + input wire [C_S00_AXI_ADDR_WIDTH-1 : 0] s00_axi_araddr, + input wire [2 : 0] s00_axi_arprot, + input wire s00_axi_arvalid, + output wire s00_axi_arready, + output wire [C_S00_AXI_DATA_WIDTH-1 : 0] s00_axi_rdata, + output wire [1 : 0] s00_axi_rresp, + output wire s00_axi_rvalid, + input wire s00_axi_rready + ); + wire [C_S00_AXI_DATA_WIDTH-1:0] reg_x; + wire [C_S00_AXI_DATA_WIDTH-1:0] reg_y; + wire [C_S00_AXI_DATA_WIDTH-1:0] reg_color; +// Instantiation of Axi Bus Interface S00_AXI + simplevga_v1_0_S00_AXI # ( + .C_S_AXI_DATA_WIDTH(C_S00_AXI_DATA_WIDTH), + .C_S_AXI_ADDR_WIDTH(C_S00_AXI_ADDR_WIDTH) + ) simplevga_v1_0_S00_AXI_inst ( + .slave_reg0(reg_x), + .slave_reg1(reg_y), + .slave_reg2(reg_color), + .S_AXI_ACLK(s00_axi_aclk), + .S_AXI_ARESETN(s00_axi_aresetn), + .S_AXI_AWADDR(s00_axi_awaddr), + .S_AXI_AWPROT(s00_axi_awprot), + .S_AXI_AWVALID(s00_axi_awvalid), + .S_AXI_AWREADY(s00_axi_awready), + .S_AXI_WDATA(s00_axi_wdata), + .S_AXI_WSTRB(s00_axi_wstrb), + .S_AXI_WVALID(s00_axi_wvalid), + .S_AXI_WREADY(s00_axi_wready), + .S_AXI_BRESP(s00_axi_bresp), + .S_AXI_BVALID(s00_axi_bvalid), + .S_AXI_BREADY(s00_axi_bready), + .S_AXI_ARADDR(s00_axi_araddr), + .S_AXI_ARPROT(s00_axi_arprot), + .S_AXI_ARVALID(s00_axi_arvalid), + .S_AXI_ARREADY(s00_axi_arready), + .S_AXI_RDATA(s00_axi_rdata), + .S_AXI_RRESP(s00_axi_rresp), + .S_AXI_RVALID(s00_axi_rvalid), + .S_AXI_RREADY(s00_axi_rready) + ); + + // Add user logic here + wire [9:0] box_x1 = reg_x[9:0]; + wire [9:0] box_x2 = reg_x[25:16]; + wire [8:0] box_y1 = reg_y[8:0]; + wire [8:0] box_y2 = reg_y[24:16]; + wire [5:0] box_color = reg_color[5:0]; + + vgasquare display ( + .CLK(s00_axi_aclk), // board clock + .PIXEL_CLK(I_PIXEL_CLK), // Pixel clock: 25Mhz (or 25.125MHz) for VGA + .RST_BTN(s00_axi_aresetn), // reset button + .box_x1(box_x1), + .box_x2(box_x2), + .box_y1(box_y1), + .box_y2(box_y2), + .box_color(box_color), //1 bit for each color Foreground and background + .VGA_ACTIVE(O_VGA_ACTIVE), + .VGA_HS(O_VGA_HS), // horizontal sync output + .VGA_VS(O_VGA_VS), // vertical sync output + .VGA_R(O_VGA_R), // 1-bit VGA red output + .VGA_G(O_VGA_G), // 1-bit VGA green output + .VGA_B(O_VGA_B) // 1-bit VGA blue output + ); + // User logic ends + + endmodule diff --git a/simplevga_v1_0_S00_AXI.v b/simplevga_v1_0_S00_AXI.v new file mode 100644 index 0000000..f9b79e8 --- /dev/null +++ b/simplevga_v1_0_S00_AXI.v @@ -0,0 +1,409 @@ + +`timescale 1 ns / 1 ps + + module simplevga_v1_0_S00_AXI # + ( + // Users to add parameters here + + // User parameters ends + // Do not modify the parameters beyond this line + + // Width of S_AXI data bus + parameter integer C_S_AXI_DATA_WIDTH = 32, + // Width of S_AXI address bus + parameter integer C_S_AXI_ADDR_WIDTH = 4 + ) + ( + // Users to add ports here + output wire [C_S_AXI_DATA_WIDTH-1:0]slave_reg0, + output wire [C_S_AXI_DATA_WIDTH-1:0]slave_reg1, + output wire [C_S_AXI_DATA_WIDTH-1:0]slave_reg2, + // User ports ends + // Do not modify the ports beyond this line + + // Global Clock Signal + input wire S_AXI_ACLK, + // Global Reset Signal. This Signal is Active LOW + input wire S_AXI_ARESETN, + // Write address (issued by master, acceped by Slave) + input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_AWADDR, + // Write channel Protection type. This signal indicates the + // privilege and security level of the transaction, and whether + // the transaction is a data access or an instruction access. + input wire [2 : 0] S_AXI_AWPROT, + // Write address valid. This signal indicates that the master signaling + // valid write address and control information. + input wire S_AXI_AWVALID, + // Write address ready. This signal indicates that the slave is ready + // to accept an address and associated control signals. + output wire S_AXI_AWREADY, + // Write data (issued by master, acceped by Slave) + input wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_WDATA, + // Write strobes. This signal indicates which byte lanes hold + // valid data. There is one write strobe bit for each eight + // bits of the write data bus. + input wire [(C_S_AXI_DATA_WIDTH/8)-1 : 0] S_AXI_WSTRB, + // Write valid. This signal indicates that valid write + // data and strobes are available. + input wire S_AXI_WVALID, + // Write ready. This signal indicates that the slave + // can accept the write data. + output wire S_AXI_WREADY, + // Write response. This signal indicates the status + // of the write transaction. + output wire [1 : 0] S_AXI_BRESP, + // Write response valid. This signal indicates that the channel + // is signaling a valid write response. + output wire S_AXI_BVALID, + // Response ready. This signal indicates that the master + // can accept a write response. + input wire S_AXI_BREADY, + // Read address (issued by master, acceped by Slave) + input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_ARADDR, + // Protection type. This signal indicates the privilege + // and security level of the transaction, and whether the + // transaction is a data access or an instruction access. + input wire [2 : 0] S_AXI_ARPROT, + // Read address valid. This signal indicates that the channel + // is signaling valid read address and control information. + input wire S_AXI_ARVALID, + // Read address ready. This signal indicates that the slave is + // ready to accept an address and associated control signals. + output wire S_AXI_ARREADY, + // Read data (issued by slave) + output wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_RDATA, + // Read response. This signal indicates the status of the + // read transfer. + output wire [1 : 0] S_AXI_RRESP, + // Read valid. This signal indicates that the channel is + // signaling the required read data. + output wire S_AXI_RVALID, + // Read ready. This signal indicates that the master can + // accept the read data and response information. + input wire S_AXI_RREADY + ); + + // AXI4LITE signals + reg [C_S_AXI_ADDR_WIDTH-1 : 0] axi_awaddr; + reg axi_awready; + reg axi_wready; + reg [1 : 0] axi_bresp; + reg axi_bvalid; + reg [C_S_AXI_ADDR_WIDTH-1 : 0] axi_araddr; + reg axi_arready; + reg [C_S_AXI_DATA_WIDTH-1 : 0] axi_rdata; + reg [1 : 0] axi_rresp; + reg axi_rvalid; + + // Example-specific design signals + // local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH + // ADDR_LSB is used for addressing 32/64 bit registers/memories + // ADDR_LSB = 2 for 32 bits (n downto 2) + // ADDR_LSB = 3 for 64 bits (n downto 3) + localparam integer ADDR_LSB = (C_S_AXI_DATA_WIDTH/32) + 1; + localparam integer OPT_MEM_ADDR_BITS = 1; + //---------------------------------------------- + //-- Signals for user logic register space example + //------------------------------------------------ + //-- Number of Slave Registers 4 + reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg0; + reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg1; + reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg2; + reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg3; + wire slv_reg_rden; + wire slv_reg_wren; + reg [C_S_AXI_DATA_WIDTH-1:0] reg_data_out; + integer byte_index; + reg aw_en; + + // I/O Connections assignments + assign slave_reg0 = slv_reg0; + assign slave_reg1 = slv_reg1; + assign slave_reg2 = slv_reg2; + // End custom assignments + assign S_AXI_AWREADY = axi_awready; + assign S_AXI_WREADY = axi_wready; + assign S_AXI_BRESP = axi_bresp; + assign S_AXI_BVALID = axi_bvalid; + assign S_AXI_ARREADY = axi_arready; + assign S_AXI_RDATA = axi_rdata; + assign S_AXI_RRESP = axi_rresp; + assign S_AXI_RVALID = axi_rvalid; + // Implement axi_awready generation + // axi_awready is asserted for one S_AXI_ACLK clock cycle when both + // S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is + // de-asserted when reset is low. + + always @( posedge S_AXI_ACLK ) + begin + if ( S_AXI_ARESETN == 1'b0 ) + begin + axi_awready <= 1'b0; + aw_en <= 1'b1; + end + else + begin + if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID && aw_en) + begin + // slave is ready to accept write address when + // there is a valid write address and write data + // on the write address and data bus. This design + // expects no outstanding transactions. + axi_awready <= 1'b1; + aw_en <= 1'b0; + end + else if (S_AXI_BREADY && axi_bvalid) + begin + aw_en <= 1'b1; + axi_awready <= 1'b0; + end + else + begin + axi_awready <= 1'b0; + end + end + end + + // Implement axi_awaddr latching + // This process is used to latch the address when both + // S_AXI_AWVALID and S_AXI_WVALID are valid. + + always @( posedge S_AXI_ACLK ) + begin + if ( S_AXI_ARESETN == 1'b0 ) + begin + axi_awaddr <= 0; + end + else + begin + if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID && aw_en) + begin + // Write Address latching + axi_awaddr <= S_AXI_AWADDR; + end + end + end + + // Implement axi_wready generation + // axi_wready is asserted for one S_AXI_ACLK clock cycle when both + // S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is + // de-asserted when reset is low. + + always @( posedge S_AXI_ACLK ) + begin + if ( S_AXI_ARESETN == 1'b0 ) + begin + axi_wready <= 1'b0; + end + else + begin + if (~axi_wready && S_AXI_WVALID && S_AXI_AWVALID && aw_en ) + begin + // slave is ready to accept write data when + // there is a valid write address and write data + // on the write address and data bus. This design + // expects no outstanding transactions. + axi_wready <= 1'b1; + end + else + begin + axi_wready <= 1'b0; + end + end + end + + // Implement memory mapped register select and write logic generation + // The write data is accepted and written to memory mapped registers when + // axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to + // select byte enables of slave registers while writing. + // These registers are cleared when reset (active low) is applied. + // Slave register write enable is asserted when valid address and data are available + // and the slave is ready to accept the write address and write data. + assign slv_reg_wren = axi_wready && S_AXI_WVALID && axi_awready && S_AXI_AWVALID; + + always @( posedge S_AXI_ACLK ) + begin + if ( S_AXI_ARESETN == 1'b0 ) + begin + slv_reg0 <= 0; + slv_reg1 <= 0; + slv_reg2 <= 0; + slv_reg3 <= 0; + end + else begin + if (slv_reg_wren) + begin + case ( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] ) + 2'h0: + for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) + if ( S_AXI_WSTRB[byte_index] == 1 ) begin + // Respective byte enables are asserted as per write strobes + // Slave register 0 + slv_reg0[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; + end + 2'h1: + for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) + if ( S_AXI_WSTRB[byte_index] == 1 ) begin + // Respective byte enables are asserted as per write strobes + // Slave register 1 + slv_reg1[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; + end + 2'h2: + for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) + if ( S_AXI_WSTRB[byte_index] == 1 ) begin + // Respective byte enables are asserted as per write strobes + // Slave register 2 + slv_reg2[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; + end + 2'h3: + for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) + if ( S_AXI_WSTRB[byte_index] == 1 ) begin + // Respective byte enables are asserted as per write strobes + // Slave register 3 + slv_reg3[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; + end + default : begin + slv_reg0 <= slv_reg0; + slv_reg1 <= slv_reg1; + slv_reg2 <= slv_reg2; + slv_reg3 <= slv_reg3; + end + endcase + end + end + end + + // Implement write response logic generation + // The write response and response valid signals are asserted by the slave + // when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. + // This marks the acceptance of address and indicates the status of + // write transaction. + + always @( posedge S_AXI_ACLK ) + begin + if ( S_AXI_ARESETN == 1'b0 ) + begin + axi_bvalid <= 0; + axi_bresp <= 2'b0; + end + else + begin + if (axi_awready && S_AXI_AWVALID && ~axi_bvalid && axi_wready && S_AXI_WVALID) + begin + // indicates a valid write response is available + axi_bvalid <= 1'b1; + axi_bresp <= 2'b0; // 'OKAY' response + end // work error responses in future + else + begin + if (S_AXI_BREADY && axi_bvalid) + //check if bready is asserted while bvalid is high) + //(there is a possibility that bready is always asserted high) + begin + axi_bvalid <= 1'b0; + end + end + end + end + + // Implement axi_arready generation + // axi_arready is asserted for one S_AXI_ACLK clock cycle when + // S_AXI_ARVALID is asserted. axi_awready is + // de-asserted when reset (active low) is asserted. + // The read address is also latched when S_AXI_ARVALID is + // asserted. axi_araddr is reset to zero on reset assertion. + + always @( posedge S_AXI_ACLK ) + begin + if ( S_AXI_ARESETN == 1'b0 ) + begin + axi_arready <= 1'b0; + axi_araddr <= 32'b0; + end + else + begin + if (~axi_arready && S_AXI_ARVALID) + begin + // indicates that the slave has acceped the valid read address + axi_arready <= 1'b1; + // Read address latching + axi_araddr <= S_AXI_ARADDR; + end + else + begin + axi_arready <= 1'b0; + end + end + end + + // Implement axi_arvalid generation + // axi_rvalid is asserted for one S_AXI_ACLK clock cycle when both + // S_AXI_ARVALID and axi_arready are asserted. The slave registers + // data are available on the axi_rdata bus at this instance. The + // assertion of axi_rvalid marks the validity of read data on the + // bus and axi_rresp indicates the status of read transaction.axi_rvalid + // is deasserted on reset (active low). axi_rresp and axi_rdata are + // cleared to zero on reset (active low). + always @( posedge S_AXI_ACLK ) + begin + if ( S_AXI_ARESETN == 1'b0 ) + begin + axi_rvalid <= 0; + axi_rresp <= 0; + end + else + begin + if (axi_arready && S_AXI_ARVALID && ~axi_rvalid) + begin + // Valid read data is available at the read data bus + axi_rvalid <= 1'b1; + axi_rresp <= 2'b0; // 'OKAY' response + end + else if (axi_rvalid && S_AXI_RREADY) + begin + // Read data is accepted by the master + axi_rvalid <= 1'b0; + end + end + end + + // Implement memory mapped register select and read logic generation + // Slave register read enable is asserted when valid address is available + // and the slave is ready to accept the read address. + assign slv_reg_rden = axi_arready & S_AXI_ARVALID & ~axi_rvalid; + always @(*) + begin + // Address decoding for reading registers + case ( axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] ) + 2'h0 : reg_data_out <= slv_reg0; + 2'h1 : reg_data_out <= slv_reg1; + 2'h2 : reg_data_out <= slv_reg2; + 2'h3 : reg_data_out <= slv_reg3; + default : reg_data_out <= 0; + endcase + end + + // Output register or memory read data + always @( posedge S_AXI_ACLK ) + begin + if ( S_AXI_ARESETN == 1'b0 ) + begin + axi_rdata <= 0; + end + else + begin + // When there is a valid read address (S_AXI_ARVALID) with + // acceptance of read address by the slave (axi_arready), + // output the read dada + if (slv_reg_rden) + begin + axi_rdata <= reg_data_out; // register read data + end + end + end + + // Add user logic here + + // User logic ends + + endmodule diff --git a/userland.c b/userland.c new file mode 100644 index 0000000..883816b --- /dev/null +++ b/userland.c @@ -0,0 +1,11 @@ + SIMPLEVGA_mWriteReg(XPAR_SIMPLEVGA_0_S00_AXI_BASEADDR, SIMPLEVGA_S00_AXI_SLV_REG0_OFFSET, 0xFFFFFFFF); + SIMPLEVGA_mWriteReg(XPAR_SIMPLEVGA_0_S00_AXI_BASEADDR, SIMPLEVGA_S00_AXI_SLV_REG1_OFFSET, 0xFFFFFFFF); + SIMPLEVGA_mWriteReg(XPAR_SIMPLEVGA_0_S00_AXI_BASEADDR, SIMPLEVGA_S00_AXI_SLV_REG2_OFFSET, 0xFFFFFFFF); + unsigned long x = 1; + while(1) { + for(x = 1; x < 100; x++) { + unsigned long xreg = ((640-x) << 16) + x; + SIMPLEVGA_mWriteReg(XPAR_SIMPLEVGA_0_S00_AXI_BASEADDR, SIMPLEVGA_S00_AXI_SLV_REG0_OFFSET, x); + //usleep(1000000); + } + } diff --git a/vga640x480.v b/vga640x480.v index 42e91f3..f0f035e 100644 --- a/vga640x480.v +++ b/vga640x480.v @@ -54,25 +54,23 @@ module vga640x480( // animate: high for one tick at the end of the final active pixel line assign o_animate = ((v_count == VA_END - 1) & (h_count == LINE)); - always @ (posedge i_clk) + always @ (posedge i_pix_stb) begin if (i_rst) // reset to start of frame begin h_count <= 0; v_count <= 0; end - if (i_pix_stb) // once per pixel - begin - if (h_count == LINE) // end of line - begin - h_count <= 0; - v_count <= v_count + 1; - end - else - h_count <= h_count + 1; - if (v_count == SCREEN) // end of screen - v_count <= 0; + if (h_count == LINE) // end of line + begin + h_count <= 0; + v_count <= v_count + 1; end + else + h_count <= h_count + 1; + + if (v_count == SCREEN) // end of screen + v_count <= 0; end -endmodule +endmodule \ No newline at end of file diff --git a/vgasquare.v b/vgasquare.v index 0e90f52..5d37b37 100644 --- a/vgasquare.v +++ b/vgasquare.v @@ -14,6 +14,7 @@ module vgasquare( input wire [8:0] box_y1, input wire [8:0] box_y2, input wire [5:0] box_color, //1 bit for each color Foreground and background + output wire VGA_ACTIVE, //High when drawing is active output wire VGA_HS, // horizontal sync output output wire VGA_VS, // vertical sync output output wire VGA_R, // 1-bit VGA red output @@ -30,6 +31,7 @@ module vgasquare( .i_clk(CLK), .i_pix_stb(PIXEL_CLK), .i_rst(rst), + .o_active(VGA_ACTIVE), .o_hs(VGA_HS), .o_vs(VGA_VS), .o_x(x), @@ -37,8 +39,7 @@ module vgasquare( ); // Draw one square - wire square; - assign square = ((x > box_x1) & (y > box_y1) & (x < box_x2) & (y < box_y2)) ? 1 : 0; //Is box within range? + wire square = ((x > box_x1) & (y > box_y1) & (x < box_x2) & (y < box_y2)) ? 1 : 0; //Is box within range? assign VGA_R = square ? box_color[0] : box_color[3]; // Set R (Foreground and then background)