URL
https://opencores.org/ocsvn/openmsp430/openmsp430/trunk
Subversion Repositories openmsp430
[/] [openmsp430/] [trunk/] [fpga/] [altera_de0_nano_soc/] [rtl/] [verilog/] [opengfx430/] [ogfx_gpu_dma_addr.v] - Rev 222
Go to most recent revision | Compare with Previous | Blame | View Log
//---------------------------------------------------------------------------- // Copyright (C) 2015 Authors // // This source file may be used and distributed without restriction provided // that this copyright statement is not removed from the file and that any // derivative work contains the original copyright notice and the associated // disclaimer. // // This source file is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published // by the Free Software Foundation; either version 2.1 of the License, or // (at your option) any later version. // // This source 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 Lesser General Public // License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this source; if not, write to the Free Software Foundation, // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // //---------------------------------------------------------------------------- // // *File Name: ogfx_gpu_dma_addr.v // // *Module Description: // Compute next Video-Ram address // // *Author(s): // - Olivier Girard, olgirard@gmail.com // //---------------------------------------------------------------------------- // $Rev$ // $LastChangedBy$ // $LastChangedDate$ //---------------------------------------------------------------------------- `ifdef OGFX_NO_INCLUDE `else `include "openGFX430_defines.v" `endif module ogfx_gpu_dma_addr ( // OUTPUTs vid_ram_addr_nxt_o, // Next Video-RAM address // INPUTs mclk, // Main system clock puc_rst, // Main system reset display_width_i, // Display width gfx_mode_1_bpp_i, // Graphic mode 1 bpp resolution gfx_mode_2_bpp_i, // Graphic mode 2 bpp resolution gfx_mode_4_bpp_i, // Graphic mode 4 bpp resolution gfx_mode_8_bpp_i, // Graphic mode 8 bpp resolution gfx_mode_16_bpp_i, // Graphic mode 16 bpp resolution vid_ram_addr_i, // Video-RAM address vid_ram_addr_init_i, // Video-RAM address initialization vid_ram_addr_step_i, // Video-RAM address step vid_ram_width_i, // Video-RAM width vid_ram_win_x_swap_i, // Video-RAM X-Swap configuration vid_ram_win_y_swap_i, // Video-RAM Y-Swap configuration vid_ram_win_cl_swap_i // Video-RAM CL-Swap configuration ); // OUTPUTs //========= output [`APIX_MSB:0] vid_ram_addr_nxt_o; // Next Video-RAM address // INPUTs //========= input mclk; // Main system clock input puc_rst; // Main system reset input [`LPIX_MSB:0] display_width_i; // Display width input gfx_mode_1_bpp_i; // Graphic mode 1 bpp resolution input gfx_mode_2_bpp_i; // Graphic mode 2 bpp resolution input gfx_mode_4_bpp_i; // Graphic mode 4 bpp resolution input gfx_mode_8_bpp_i; // Graphic mode 8 bpp resolution input gfx_mode_16_bpp_i; // Graphic mode 16 bpp resolution input [`APIX_MSB:0] vid_ram_addr_i; // Video-RAM address input vid_ram_addr_init_i; // Video-RAM address initialization input vid_ram_addr_step_i; // Video-RAM address step input [`LPIX_MSB:0] vid_ram_width_i; // Video-RAM width input vid_ram_win_x_swap_i; // Video-RAM X-Swap configuration input vid_ram_win_y_swap_i; // Video-RAM Y-Swap configuration input vid_ram_win_cl_swap_i; // Video-RAM CL-Swap configuration //============================================================================= // 1) COMPUTE NEXT MEMORY ACCESS //============================================================================= reg [`APIX_MSB:0] vid_ram_line_addr; reg [`LPIX_MSB:0] vid_ram_column_count; // Detect when the current line refresh is done wire vid_ram_line_done = vid_ram_addr_step_i & (vid_ram_column_count==(vid_ram_width_i-{{`LPIX_MSB{1'b0}}, 1'b1})); // Mux between initialization value and display width wire [`LPIX_MSB:0] vid_ram_length_mux = vid_ram_addr_init_i ? vid_ram_width_i : display_width_i ; // Align depending on graphic mode wire [`LPIX_MSB+4:0] vid_ram_length_align = {`LPIX_MSB+5{gfx_mode_1_bpp_i }} & {4'b0000, vid_ram_length_mux[`LPIX_MSB:0] } | {`LPIX_MSB+5{gfx_mode_2_bpp_i }} & {3'b000, vid_ram_length_mux[`LPIX_MSB:0], 1'b0 } | {`LPIX_MSB+5{gfx_mode_4_bpp_i }} & {2'b00, vid_ram_length_mux[`LPIX_MSB:0], 2'b00 } | {`LPIX_MSB+5{gfx_mode_8_bpp_i }} & {1'b0, vid_ram_length_mux[`LPIX_MSB:0], 3'b000 } | {`LPIX_MSB+5{gfx_mode_16_bpp_i}} & { vid_ram_length_mux[`LPIX_MSB:0], 4'b0000} ; wire [`APIX_MSB:0] plus_one_val = {`APIX_MSB+1{gfx_mode_1_bpp_i }} & {4'b0000, {{`VRAM_MSB{1'b0}}, 1'b1} } | {`APIX_MSB+1{gfx_mode_2_bpp_i }} & {3'b000, {{`VRAM_MSB{1'b0}}, 1'b1}, 1'b0 } | {`APIX_MSB+1{gfx_mode_4_bpp_i }} & {2'b00, {{`VRAM_MSB{1'b0}}, 1'b1}, 2'b00 } | {`APIX_MSB+1{gfx_mode_8_bpp_i }} & {1'b0, {{`VRAM_MSB{1'b0}}, 1'b1}, 3'b000 } | {`APIX_MSB+1{gfx_mode_16_bpp_i}} & { {{`VRAM_MSB{1'b0}}, 1'b1}, 4'b0000} ; // Zero extension for LINT cleanup wire [`APIX_MSB*3:0] vid_ram_length_norm = {{`APIX_MSB*3-`LPIX_MSB-4{1'b0}}, vid_ram_length_align}; // Select base address for next calculation wire [`APIX_MSB:0] next_base_addr = (vid_ram_addr_init_i | ~vid_ram_line_done) ? vid_ram_addr_i : vid_ram_line_addr ; // Compute next address wire [`APIX_MSB:0] next_addr = next_base_addr + (vid_ram_length_norm[`APIX_MSB:0] & {`APIX_MSB+1{~vid_ram_addr_init_i ? (~vid_ram_win_y_swap_i & (vid_ram_win_cl_swap_i ^ vid_ram_line_done)) : 1'b0}}) - (vid_ram_length_norm[`APIX_MSB:0] & {`APIX_MSB+1{~vid_ram_addr_init_i ? ( vid_ram_win_y_swap_i & (vid_ram_win_cl_swap_i ^ vid_ram_line_done)) : 1'b0}}) + (plus_one_val & {`APIX_MSB+1{~vid_ram_addr_init_i ? (~vid_ram_win_x_swap_i & ~(vid_ram_win_cl_swap_i ^ vid_ram_line_done)) : 1'b0}}) - (plus_one_val & {`APIX_MSB+1{~vid_ram_addr_init_i ? ( vid_ram_win_x_swap_i & ~(vid_ram_win_cl_swap_i ^ vid_ram_line_done)) : 1'b0}}); wire update_line_addr = vid_ram_addr_init_i | vid_ram_line_done; wire update_pixel_addr = update_line_addr | vid_ram_addr_step_i; // Start RAM address of currentely refreshed line always @(posedge mclk or posedge puc_rst) if (puc_rst) vid_ram_line_addr <= {`APIX_MSB+1{1'b0}}; else if (update_line_addr) vid_ram_line_addr <= next_addr; // Current RAM address of the currentely refreshed pixel assign vid_ram_addr_nxt_o = update_pixel_addr ? next_addr : vid_ram_addr_i; // Count the pixel number in the current line // (used to detec the end of a line) always @(posedge mclk or posedge puc_rst) if (puc_rst) vid_ram_column_count <= {`LPIX_MSB+1{1'b0}}; else if (vid_ram_addr_init_i) vid_ram_column_count <= {`LPIX_MSB+1{1'b0}}; else if (vid_ram_line_done) vid_ram_column_count <= {`LPIX_MSB+1{1'b0}}; else if (vid_ram_addr_step_i) vid_ram_column_count <= vid_ram_column_count + {{`LPIX_MSB{1'b0}}, 1'b1}; endmodule // ogfx_calc_vram_addr `ifdef OGFX_NO_INCLUDE `else `include "openGFX430_undefines.v" `endif
Go to most recent revision | Compare with Previous | Blame | View Log