URL
https://opencores.org/ocsvn/opengfx430/opengfx430/trunk
Subversion Repositories opengfx430
Compare Revisions
- This comparison shows the changes necessary to convert path
/opengfx430
- from Rev 2 to Rev 3
- ↔ Reverse comparison
Rev 2 → Rev 3
/trunk/core/rtl/verilog/ogfx_gpu_reg.v
0,0 → 1,685
//---------------------------------------------------------------------------- |
// 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_reg.v |
// |
// *Module Description: |
// Configuration registers of the Graphic-Processing unit |
// |
// *Author(s): |
// - Olivier Girard, olgirard@gmail.com |
// |
//---------------------------------------------------------------------------- |
// $Rev$ |
// $LastChangedBy$ |
// $LastChangedDate$ |
//---------------------------------------------------------------------------- |
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_defines.v" |
`endif |
|
module ogfx_gpu_reg ( |
|
// OUTPUTs |
cfg_dst_px_addr_o, // Destination pixel address configuration |
cfg_dst_cl_swp_o, // Destination Column/Line-Swap configuration |
cfg_dst_x_swp_o, // Destination X-Swap configuration |
cfg_dst_y_swp_o, // Destination Y-Swap configuration |
cfg_fill_color_o, // Fill color (for rectangle fill operation) |
cfg_pix_op_sel_o, // Pixel operation to be performed during the copy |
cfg_rec_width_o, // Rectangle width configuration |
cfg_rec_height_o, // Rectangle height configuration |
cfg_src_px_addr_o, // Source pixel address configuration |
cfg_src_cl_swp_o, // Source Column/Line-Swap configuration |
cfg_src_x_swp_o, // Source X-Swap configuration |
cfg_src_y_swp_o, // Source Y-Swap configuration |
cfg_transparent_color_o, // Transparent color (for rectangle transparent copy operation) |
|
gpu_cmd_done_evt_o, // GPU command done event |
gpu_cmd_error_evt_o, // GPU command error event |
gpu_get_data_o, // GPU get next data |
|
exec_fill_o, // Rectangle fill on going |
exec_copy_o, // Rectangle copy on going |
exec_copy_trans_o, // Rectangle transparent copy on going |
trig_exec_o, // Trigger rectangle execution |
|
// INPUTs |
mclk, // Main system clock |
puc_rst, // Main system reset |
|
gpu_data_i, // GPU data |
gpu_data_avail_i, // GPU data available |
gfx_mode_i, // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp) |
gpu_enable_i, // GPU enable |
|
gpu_exec_done_i // GPU execution done |
); |
|
// OUTPUTs |
//========= |
output [`APIX_MSB:0] cfg_dst_px_addr_o; // Destination pixel address configuration |
output cfg_dst_cl_swp_o; // Destination Column/Line-Swap configuration |
output cfg_dst_x_swp_o; // Destination X-Swap configuration |
output cfg_dst_y_swp_o; // Destination Y-Swap configuration |
output [15:0] cfg_fill_color_o; // Fill color (for rectangle fill operation) |
output [3:0] cfg_pix_op_sel_o; // Pixel operation to be performed during the copy |
output [`LPIX_MSB:0] cfg_rec_width_o; // Rectangle width configuration |
output [`LPIX_MSB:0] cfg_rec_height_o; // Rectangle height configuration |
output [`APIX_MSB:0] cfg_src_px_addr_o; // Source pixel address configuration |
output cfg_src_cl_swp_o; // Source Column/Line-Swap configuration |
output cfg_src_x_swp_o; // Source X-Swap configuration |
output cfg_src_y_swp_o; // Source Y-Swap configuration |
output [15:0] cfg_transparent_color_o; // Transparent color (for rectangle transparent copy operation) |
|
output gpu_cmd_done_evt_o; // GPU command done event |
output gpu_cmd_error_evt_o; // GPU command error event |
output gpu_get_data_o; // GPU get next data |
|
output exec_fill_o; // Rectangle fill on going |
output exec_copy_o; // Rectangle copy on going |
output exec_copy_trans_o; // Rectangle transparent copy on going |
output trig_exec_o; // Trigger rectangle execution |
|
// INPUTs |
//========= |
input mclk; // Main system clock |
input puc_rst; // Main system reset |
|
input [15:0] gpu_data_i; // GPU data |
input gpu_data_avail_i; // GPU data available |
input [2:0] gfx_mode_i; // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp) |
input gpu_enable_i; // GPU enable |
|
input gpu_exec_done_i; // GPU execution done |
|
//============================================================================= |
// 1) WIRE, REGISTERS AND PARAMETER DECLARATION |
//============================================================================= |
|
// Video modes decoding |
wire gfx_mode_1_bpp = (gfx_mode_i == 3'b000); |
wire gfx_mode_2_bpp = (gfx_mode_i == 3'b001); |
wire gfx_mode_4_bpp = (gfx_mode_i == 3'b010); |
wire gfx_mode_8_bpp = (gfx_mode_i == 3'b011); |
wire gfx_mode_16_bpp = ~(gfx_mode_8_bpp | gfx_mode_4_bpp | gfx_mode_2_bpp | gfx_mode_1_bpp); |
|
// Remaining wires/registers |
reg exec_fill_o; |
reg exec_copy_o; |
reg exec_copy_trans_o; |
|
reg [1:0] src_offset_sel; |
reg src_x_swp; |
reg src_y_swp; |
reg src_cl_swp; |
reg [3:0] pix_op_sel; |
reg [1:0] dst_offset_sel; |
reg dst_x_swp; |
reg dst_y_swp; |
reg dst_cl_swp; |
|
reg [3:0] reg_access; |
wire [3:0] reg_access_nxt; |
|
reg [15:0] fill_color; |
reg [`LPIX_MSB:0] rec_width; |
reg [`LPIX_MSB:0] rec_height; |
wire [`APIX_MSB:0] src_px_addr; |
wire [`APIX_MSB:0] src_px_addr_align; |
wire [`APIX_MSB:0] dst_px_addr; |
wire [`APIX_MSB:0] dst_px_addr_align; |
wire [`APIX_MSB:0] of0_addr; |
wire [`APIX_MSB:0] of1_addr; |
wire [`APIX_MSB:0] of2_addr; |
wire [`APIX_MSB:0] of3_addr; |
reg [15:0] transparent_color; |
|
wire [`APIX_MSB:0] src_offset_addr; |
wire [`APIX_MSB:0] dst_offset_addr; |
|
|
//============================================================================= |
// 2) GPU COMMAND STATE MACHINE |
//============================================================================= |
// |
// EXEC_FILL - Execute rectangle fill command |
// {2'b00, reserved<4:0>, pxop[3:0], dst_offset[1:0], dst_X-Swp, dst_Y-Swp, dst_CL-Swp} |
// {fill_color[15:0]} |
// |
// EXEC_COPY - Execute rectangle copy command |
// {2'b01, src_offset[1:0], src_X-Swp, src_Y-Swp, src_CL-Swp, pxop[3:0], dst_offset[1:0], dst_X-Swp, dst_Y-Swp, dst_CL-Swp} |
// |
// EXEC_COPY_TRANS - Execute rectangle copy with transparency command |
// {2'b10, src_offset[1:0], src_X-Swp, src_Y-Swp, src_CL-Swp, pxop[3:0], dst_offset[1:0], dst_X-Swp, dst_Y-Swp, dst_CL-Swp} |
// |
// REC_WIDTH - Set rectangle width |
// {4'b1100, width[11:0]} |
// |
// REC_HEIGHT - Set rectangle height |
// {4'b1101, height[11:0]} |
// |
// SRC_PX_ADDR - Set source address |
// {4'b1111, 2'b10, 10'b0000000000} |
// {addr[31:16] } |
// {addr[15:0] } |
// |
// DST_PX_ADDR - Set destination address |
// {4'b1111, 2'b10, 10'b0000000001} |
// {addr[31:16] } |
// {addr[15:0] } |
// |
// OF0_ADDR - Set address offset 0 |
// {4'b1111, 2'b10, 10'b0000010000} |
// {addr[31:16] } |
// {addr[15:0] } |
// |
// OF1_ADDR - Set address offset 1 |
// {4'b1111, 2'b10, 10'b0000010001} |
// {addr[31:16] } |
// {addr[15:0] } |
// |
// OF2_ADDR - Set address offset 2 |
// {4'b1111, 2'b10, 10'b0000010010} |
// {addr[31:16] } |
// {addr[15:0] } |
// |
// OF3_ADDR - Set address offset 3 |
// {4'b1111, 2'b10, 10'b0000010011} |
// {addr[31:16] } |
// {addr[15:0] } |
// |
// SET_FILL - Set fill color |
// {4'b1111, 2'b01, 10'b0000100000} |
// {fill_color[15:0] } |
// |
// SET_TRANSPARENT - Set transparent color |
// {4'b1111, 2'b01, 10'b0000100001} |
// {transparent_color[15:0] } |
// |
//----------------------------------------------------------------------------- |
|
// State definition |
parameter CMD_WAIT = 4'h0; |
parameter CMD_READ = 4'h1; |
parameter DATA1B_WAIT = 4'h2; |
parameter DATA1B_READ = 4'h3; |
parameter DATA2B1_WAIT = 4'h4; |
parameter DATA2B1_READ = 4'h5; |
parameter DATA2B2_WAIT = 4'h6; |
parameter DATA2B2_READ = 4'h7; |
parameter EXEC_START = 4'h8; |
parameter EXEC = 4'h9; |
parameter ERROR = 4'hA; |
|
// State machine |
reg [3:0] gpu_state; |
reg [3:0] gpu_state_nxt; |
|
// Arcs control |
wire cmd_available = gpu_data_avail_i; |
|
wire cmd_not_valid = ((gpu_data_i[15:14]!= `OP_EXEC_FILL ) & |
(gpu_data_i[15:14]!= `OP_EXEC_COPY ) & |
(gpu_data_i[15:14]!= `OP_EXEC_COPY_TRANS) & |
(gpu_data_i[15:12]!= `OP_REC_WIDTH ) & |
(gpu_data_i[15:12]!= `OP_REC_HEIGHT ) & |
(gpu_data_i[15:0] != `OP_SRC_PX_ADDR ) & |
(gpu_data_i[15:0] != `OP_DST_PX_ADDR ) & |
(gpu_data_i[15:0] != `OP_OF0_ADDR ) & |
(gpu_data_i[15:0] != `OP_OF1_ADDR ) & |
(gpu_data_i[15:0] != `OP_OF2_ADDR ) & |
(gpu_data_i[15:0] != `OP_OF3_ADDR ) & |
(gpu_data_i[15:0] != `OP_SET_FILL ) & |
(gpu_data_i[15:0] != `OP_SET_TRANSPARENT)); |
|
wire cmd_has_1b_data = (gpu_data_i[15:14]== `OP_EXEC_FILL ) | |
(gpu_data_i[15:0] == `OP_SET_FILL ) | |
(gpu_data_i[15:0] == `OP_SET_TRANSPARENT); |
|
wire cmd_has_2b_data = (gpu_data_i[15:0] == `OP_SRC_PX_ADDR ) | |
(gpu_data_i[15:0] == `OP_DST_PX_ADDR ) | |
(gpu_data_i[15:0] == `OP_OF0_ADDR ) | |
(gpu_data_i[15:0] == `OP_OF1_ADDR ) | |
(gpu_data_i[15:0] == `OP_OF2_ADDR ) | |
(gpu_data_i[15:0] == `OP_OF3_ADDR ); |
|
wire cmd_has_exec = exec_fill_o | exec_copy_o | exec_copy_trans_o; |
|
wire data_available = gpu_data_avail_i; |
|
|
// State transition |
always @(gpu_state or cmd_available or cmd_not_valid or cmd_has_1b_data or cmd_has_2b_data or cmd_has_exec or data_available or gpu_exec_done_i) |
case (gpu_state) |
CMD_WAIT : gpu_state_nxt = cmd_available ? CMD_READ : CMD_WAIT ; |
CMD_READ : gpu_state_nxt = cmd_not_valid ? ERROR : |
cmd_has_1b_data ? DATA1B_WAIT : |
cmd_has_2b_data ? DATA2B1_WAIT : |
cmd_has_exec ? EXEC_START : CMD_WAIT ; |
|
DATA1B_WAIT : gpu_state_nxt = data_available ? DATA1B_READ : DATA1B_WAIT ; |
DATA1B_READ : gpu_state_nxt = cmd_has_exec ? EXEC_START : CMD_WAIT ; |
|
DATA2B1_WAIT : gpu_state_nxt = data_available ? DATA2B1_READ : DATA2B1_WAIT ; |
DATA2B1_READ : gpu_state_nxt = DATA2B2_WAIT ; |
|
DATA2B2_WAIT : gpu_state_nxt = data_available ? DATA2B2_READ : DATA2B2_WAIT ; |
DATA2B2_READ : gpu_state_nxt = cmd_has_exec ? EXEC_START : CMD_WAIT ; |
|
EXEC_START : gpu_state_nxt = gpu_exec_done_i ? CMD_WAIT : EXEC ; |
EXEC : gpu_state_nxt = gpu_exec_done_i ? CMD_WAIT : EXEC ; |
ERROR : gpu_state_nxt = ERROR ; |
// pragma coverage off |
default : gpu_state_nxt = CMD_WAIT ; |
// pragma coverage on |
endcase |
|
|
// State machine |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) gpu_state <= CMD_WAIT; |
else if (~gpu_enable_i) gpu_state <= CMD_WAIT; |
else gpu_state <= gpu_state_nxt; |
|
|
// Event generation, fifo data request |
assign gpu_cmd_done_evt_o = (gpu_state!=ERROR) & (gpu_state!=CMD_WAIT) & (gpu_state_nxt==CMD_WAIT); |
assign gpu_cmd_error_evt_o = (gpu_state==ERROR); |
assign gpu_get_data_o = (gpu_state==CMD_READ) | (gpu_state==DATA1B_READ) | (gpu_state==DATA2B1_READ) | (gpu_state==DATA2B2_READ); |
|
// Execution triggers |
assign trig_exec_o = (exec_fill_o | |
exec_copy_o | |
exec_copy_trans_o) & (gpu_state==EXEC_START); |
|
|
//============================================================================= |
// 3) CONFIGURATION REGISTERS |
//============================================================================= |
|
// Detect execution commands |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) exec_fill_o <= 1'b0; |
else if ((gpu_state==CMD_WAIT) & cmd_available) exec_fill_o <= (gpu_data_i[15:14]==`OP_EXEC_FILL); |
else if ((gpu_state_nxt==CMD_WAIT) ) exec_fill_o <= 1'b0; |
|
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) exec_copy_o <= 1'b0; |
else if ((gpu_state==CMD_WAIT) & cmd_available) exec_copy_o <= (gpu_data_i[15:14]==`OP_EXEC_COPY); |
else if ((gpu_state_nxt==CMD_WAIT) ) exec_copy_o <= 1'b0; |
|
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) exec_copy_trans_o <= 1'b0; |
else if ((gpu_state==CMD_WAIT) & cmd_available) exec_copy_trans_o <= (gpu_data_i[15:14]==`OP_EXEC_COPY_TRANS); |
else if ((gpu_state_nxt==CMD_WAIT) ) exec_copy_trans_o <= 1'b0; |
|
// Detect register accesses |
parameter REG_EXEC_FILL = 4'h1; |
parameter REG_REC_WIDTH = 4'h2; |
parameter REG_REC_HEIGHT = 4'h3; |
parameter REG_SRC_PX_ADDR = 4'h4; |
parameter REG_DST_PX_ADDR = 4'h5; |
parameter REG_OF0_ADDR = 4'h6; |
parameter REG_OF1_ADDR = 4'h7; |
parameter REG_OF2_ADDR = 4'h8; |
parameter REG_OF3_ADDR = 4'h9; |
parameter REG_SET_FILL = 4'hA; |
parameter REG_SET_TRANSPARENT = 4'hB; |
|
assign reg_access_nxt = ({4{gpu_data_i[15:14]== `OP_EXEC_FILL }} & REG_EXEC_FILL ) | |
({4{gpu_data_i[15:12]== `OP_REC_WIDTH }} & REG_REC_WIDTH ) | |
({4{gpu_data_i[15:12]== `OP_REC_HEIGHT }} & REG_REC_HEIGHT ) | |
({4{gpu_data_i[15:0] == `OP_SRC_PX_ADDR }} & REG_SRC_PX_ADDR ) | |
({4{gpu_data_i[15:0] == `OP_DST_PX_ADDR }} & REG_DST_PX_ADDR ) | |
({4{gpu_data_i[15:0] == `OP_OF0_ADDR }} & REG_OF0_ADDR ) | |
({4{gpu_data_i[15:0] == `OP_OF1_ADDR }} & REG_OF1_ADDR ) | |
({4{gpu_data_i[15:0] == `OP_OF2_ADDR }} & REG_OF2_ADDR ) | |
({4{gpu_data_i[15:0] == `OP_OF3_ADDR }} & REG_OF3_ADDR ) | |
({4{gpu_data_i[15:0] == `OP_SET_FILL }} & REG_SET_FILL ) | |
({4{gpu_data_i[15:0] == `OP_SET_TRANSPARENT}} & REG_SET_TRANSPARENT) ; |
|
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) reg_access <= 4'h0; |
else if (gpu_state==CMD_READ) reg_access <= reg_access_nxt; |
else if (gpu_state_nxt==CMD_WAIT) reg_access <= 4'h0; |
|
|
//============================================================================= |
// 4) CONFIGURATION REGISTERS |
//============================================================================= |
|
//------------------------------------------------ |
// EXECUTION CONFIG Register |
//------------------------------------------------ |
|
wire exec_all_cfg_wr = (exec_fill_o | exec_copy_o | exec_copy_trans_o) & (gpu_state==CMD_READ); |
wire exec_src_cfg_wr = ( exec_copy_o | exec_copy_trans_o) & (gpu_state==CMD_READ); |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) |
begin |
src_offset_sel <= 2'b00; |
src_x_swp <= 1'b0; |
src_y_swp <= 1'b0; |
src_cl_swp <= 1'b0; |
end |
else if (exec_src_cfg_wr) |
begin |
src_offset_sel <= gpu_data_i[13:12]; |
src_x_swp <= gpu_data_i[11]; |
src_y_swp <= gpu_data_i[10]; |
src_cl_swp <= gpu_data_i[9]; |
end |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) |
begin |
pix_op_sel <= 4'b0000; |
dst_offset_sel <= 2'b00; |
dst_x_swp <= 1'b0; |
dst_y_swp <= 1'b0; |
dst_cl_swp <= 1'b0; |
end |
else if (exec_all_cfg_wr) |
begin |
pix_op_sel <= gpu_data_i[8:5]; |
dst_offset_sel <= gpu_data_i[4:3]; |
dst_x_swp <= gpu_data_i[2]; |
dst_y_swp <= gpu_data_i[1]; |
dst_cl_swp <= gpu_data_i[0]; |
end |
|
assign cfg_src_x_swp_o = src_x_swp; |
assign cfg_src_y_swp_o = src_y_swp; |
assign cfg_src_cl_swp_o = src_cl_swp; |
assign cfg_pix_op_sel_o = pix_op_sel; |
assign cfg_dst_x_swp_o = dst_x_swp; |
assign cfg_dst_y_swp_o = dst_y_swp; |
assign cfg_dst_cl_swp_o = dst_cl_swp; |
|
//------------------------------------------------ |
// FILL_COLOR Register |
//------------------------------------------------ |
|
wire fill_color_wr = ((reg_access==REG_EXEC_FILL) | |
(reg_access==REG_SET_FILL ) ) & (gpu_state==DATA1B_READ); |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) fill_color <= 16'h0000; |
else if (fill_color_wr) fill_color <= gpu_data_i; |
|
assign cfg_fill_color_o = fill_color; |
|
//------------------------------------------------ |
// REC_WIDTH Register |
//------------------------------------------------ |
|
wire rec_width_wr = (reg_access_nxt==REG_REC_WIDTH) & (gpu_state==CMD_READ); |
|
wire [`LPIX_MSB:0] rec_w_h_nxt = (|gpu_data_i[`LPIX_MSB:0]) ? gpu_data_i[`LPIX_MSB:0] : |
{{`LPIX_MSB{1'b0}}, 1'b1}; |
|
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) rec_width <= {{`LPIX_MSB{1'b0}}, 1'b1}; |
else if (rec_width_wr) rec_width <= rec_w_h_nxt; |
|
assign cfg_rec_width_o = rec_width; |
|
//------------------------------------------------ |
// REC_HEIGHT Register |
//------------------------------------------------ |
|
wire rec_height_wr = (reg_access_nxt==REG_REC_HEIGHT) & (gpu_state==CMD_READ); |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) rec_height <= {{`LPIX_MSB{1'b0}}, 1'b1}; |
else if (rec_height_wr) rec_height <= rec_w_h_nxt; |
|
assign cfg_rec_height_o = rec_height; |
|
//------------------------------------------------ |
// SRC_PX_ADDR_HI Register |
//------------------------------------------------ |
`ifdef VRAM_BIGGER_4_KW |
reg [`APIX_HI_MSB:0] src_px_addr_hi; |
|
wire src_px_addr_hi_wr = (reg_access==REG_SRC_PX_ADDR) & (gpu_state==DATA2B1_READ); |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) src_px_addr_hi <= {`APIX_HI_MSB+1{1'b0}}; |
else if (src_px_addr_hi_wr) src_px_addr_hi <= gpu_data_i[`APIX_HI_MSB:0]; |
`endif |
|
//------------------------------------------------ |
// SRC_PX_ADDR_LO Register |
//------------------------------------------------ |
reg [`APIX_LO_MSB:0] src_px_addr_lo; |
|
wire src_px_addr_lo_wr = (reg_access==REG_SRC_PX_ADDR) & (gpu_state==DATA2B2_READ); |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) src_px_addr_lo <= {`APIX_LO_MSB+1{1'b0}}; |
else if (src_px_addr_lo_wr) src_px_addr_lo <= gpu_data_i[`APIX_LO_MSB:0]; |
|
`ifdef VRAM_BIGGER_4_KW |
assign src_px_addr = {src_px_addr_hi[`APIX_HI_MSB:0], src_px_addr_lo}; |
`else |
assign src_px_addr = {src_px_addr_lo[`APIX_LO_MS:0]}; |
`endif |
|
assign src_px_addr_align = src_px_addr + src_offset_addr; |
assign cfg_src_px_addr_o = {`APIX_MSB+1{gfx_mode_1_bpp }} & {src_px_addr_align[`APIX_MSB:0] } | |
{`APIX_MSB+1{gfx_mode_2_bpp }} & {src_px_addr_align[`APIX_MSB-1:0], 1'b0 } | |
{`APIX_MSB+1{gfx_mode_4_bpp }} & {src_px_addr_align[`APIX_MSB-2:0], 2'b00 } | |
{`APIX_MSB+1{gfx_mode_8_bpp }} & {src_px_addr_align[`APIX_MSB-3:0], 3'b000 } | |
{`APIX_MSB+1{gfx_mode_16_bpp}} & {src_px_addr_align[`APIX_MSB-4:0], 4'b0000} ; |
|
//------------------------------------------------ |
// DST_PX_ADDR_HI Register |
//------------------------------------------------ |
`ifdef VRAM_BIGGER_4_KW |
reg [`APIX_HI_MSB:0] dst_px_addr_hi; |
|
wire dst_px_addr_hi_wr = (reg_access==REG_DST_PX_ADDR) & (gpu_state==DATA2B1_READ); |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) dst_px_addr_hi <= {`APIX_HI_MSB+1{1'b0}}; |
else if (dst_px_addr_hi_wr) dst_px_addr_hi <= gpu_data_i[`APIX_HI_MSB:0]; |
`endif |
|
//------------------------------------------------ |
// DST_PX_ADDR_LO Register |
//------------------------------------------------ |
reg [`APIX_LO_MSB:0] dst_px_addr_lo; |
|
wire dst_px_addr_lo_wr = (reg_access==REG_DST_PX_ADDR) & (gpu_state==DATA2B2_READ); |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) dst_px_addr_lo <= {`APIX_LO_MSB+1{1'b0}}; |
else if (dst_px_addr_lo_wr) dst_px_addr_lo <= gpu_data_i[`APIX_LO_MSB:0]; |
|
`ifdef VRAM_BIGGER_4_KW |
assign dst_px_addr = {dst_px_addr_hi[`APIX_HI_MSB:0], dst_px_addr_lo}; |
`else |
assign dst_px_addr = {dst_px_addr_lo[`APIX_LO_MS:0]}; |
`endif |
|
assign dst_px_addr_align = dst_px_addr + dst_offset_addr; |
assign cfg_dst_px_addr_o = {`APIX_MSB+1{gfx_mode_1_bpp }} & {dst_px_addr_align[`APIX_MSB:0] } | |
{`APIX_MSB+1{gfx_mode_2_bpp }} & {dst_px_addr_align[`APIX_MSB-1:0], 1'b0 } | |
{`APIX_MSB+1{gfx_mode_4_bpp }} & {dst_px_addr_align[`APIX_MSB-2:0], 2'b00 } | |
{`APIX_MSB+1{gfx_mode_8_bpp }} & {dst_px_addr_align[`APIX_MSB-3:0], 3'b000 } | |
{`APIX_MSB+1{gfx_mode_16_bpp}} & {dst_px_addr_align[`APIX_MSB-4:0], 4'b0000} ; |
|
//------------------------------------------------ |
// OF0_ADDR_HI Register |
//------------------------------------------------ |
`ifdef VRAM_BIGGER_4_KW |
reg [`APIX_HI_MSB:0] of0_addr_hi; |
|
wire of0_addr_hi_wr = (reg_access==REG_OF0_ADDR) & (gpu_state==DATA2B1_READ); |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) of0_addr_hi <= {`APIX_HI_MSB+1{1'b0}}; |
else if (of0_addr_hi_wr) of0_addr_hi <= gpu_data_i[`APIX_HI_MSB:0]; |
`endif |
|
//------------------------------------------------ |
// OF0_ADDR_LO Register |
//------------------------------------------------ |
reg [`APIX_LO_MSB:0] of0_addr_lo; |
|
wire of0_addr_lo_wr = (reg_access==REG_OF0_ADDR) & (gpu_state==DATA2B2_READ); |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) of0_addr_lo <= {`APIX_LO_MSB+1{1'b0}}; |
else if (of0_addr_lo_wr) of0_addr_lo <= gpu_data_i[`APIX_LO_MSB:0]; |
|
`ifdef VRAM_BIGGER_4_KW |
assign of0_addr = {of0_addr_hi[`APIX_HI_MSB:0], of0_addr_lo}; |
`else |
assign of0_addr = {of0_addr_lo[`APIX_LO_MS:0]}; |
`endif |
|
//------------------------------------------------ |
// OF1_ADDR_HI Register |
//------------------------------------------------ |
`ifdef VRAM_BIGGER_4_KW |
reg [`APIX_HI_MSB:0] of1_addr_hi; |
|
wire of1_addr_hi_wr = (reg_access==REG_OF1_ADDR) & (gpu_state==DATA2B1_READ); |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) of1_addr_hi <= {`APIX_HI_MSB+1{1'b0}}; |
else if (of1_addr_hi_wr) of1_addr_hi <= gpu_data_i[`APIX_HI_MSB:0]; |
`endif |
|
//------------------------------------------------ |
// OF1_ADDR_LO Register |
//------------------------------------------------ |
reg [`APIX_LO_MSB:0] of1_addr_lo; |
|
wire of1_addr_lo_wr = (reg_access==REG_OF1_ADDR) & (gpu_state==DATA2B2_READ); |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) of1_addr_lo <= {`APIX_LO_MSB+1{1'b0}}; |
else if (of1_addr_lo_wr) of1_addr_lo <= gpu_data_i[`APIX_LO_MSB:0]; |
|
`ifdef VRAM_BIGGER_4_KW |
assign of1_addr = {of1_addr_hi[`APIX_HI_MSB:0], of1_addr_lo}; |
`else |
assign of1_addr = {of1_addr_lo[`APIX_LO_MS:0]}; |
`endif |
|
//------------------------------------------------ |
// OF2_ADDR_HI Register |
//------------------------------------------------ |
`ifdef VRAM_BIGGER_4_KW |
reg [`APIX_HI_MSB:0] of2_addr_hi; |
|
wire of2_addr_hi_wr = (reg_access==REG_OF2_ADDR) & (gpu_state==DATA2B1_READ); |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) of2_addr_hi <= {`APIX_HI_MSB+1{1'b0}}; |
else if (of2_addr_hi_wr) of2_addr_hi <= gpu_data_i[`APIX_HI_MSB:0]; |
`endif |
|
//------------------------------------------------ |
// OF2_ADDR_LO Register |
//------------------------------------------------ |
reg [`APIX_LO_MSB:0] of2_addr_lo; |
|
wire of2_addr_lo_wr = (reg_access==REG_OF2_ADDR) & (gpu_state==DATA2B2_READ); |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) of2_addr_lo <= {`APIX_LO_MSB+1{1'b0}}; |
else if (of2_addr_lo_wr) of2_addr_lo <= gpu_data_i[`APIX_LO_MSB:0]; |
|
`ifdef VRAM_BIGGER_4_KW |
assign of2_addr = {of2_addr_hi[`APIX_HI_MSB:0], of2_addr_lo}; |
`else |
assign of2_addr = {of2_addr_lo[`APIX_LO_MS:0]}; |
`endif |
|
//------------------------------------------------ |
// OF3_ADDR_HI Register |
//------------------------------------------------ |
`ifdef VRAM_BIGGER_4_KW |
reg [`APIX_HI_MSB:0] of3_addr_hi; |
|
wire of3_addr_hi_wr = (reg_access==REG_OF3_ADDR) & (gpu_state==DATA2B1_READ); |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) of3_addr_hi <= {`APIX_HI_MSB+1{1'b0}}; |
else if (of3_addr_hi_wr) of3_addr_hi <= gpu_data_i[`APIX_HI_MSB:0]; |
`endif |
|
//------------------------------------------------ |
// OF3_ADDR_LO Register |
//------------------------------------------------ |
reg [`APIX_LO_MSB:0] of3_addr_lo; |
|
wire of3_addr_lo_wr = (reg_access==REG_OF3_ADDR) & (gpu_state==DATA2B2_READ); |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) of3_addr_lo <= {`APIX_LO_MSB+1{1'b0}}; |
else if (of3_addr_lo_wr) of3_addr_lo <= gpu_data_i[`APIX_LO_MSB:0]; |
|
`ifdef VRAM_BIGGER_4_KW |
assign of3_addr = {of3_addr_hi[`APIX_HI_MSB:0], of3_addr_lo}; |
`else |
assign of3_addr = {of3_addr_lo[`APIX_LO_MS:0]}; |
`endif |
|
// Offset address selection |
assign src_offset_addr = (src_offset_sel==2'h0) ? of0_addr : |
(src_offset_sel==2'h1) ? of1_addr : |
(src_offset_sel==2'h2) ? of2_addr : of3_addr; |
|
assign dst_offset_addr = (dst_offset_sel==2'h0) ? of0_addr : |
(dst_offset_sel==2'h1) ? of1_addr : |
(dst_offset_sel==2'h2) ? of2_addr : of3_addr; |
|
|
//------------------------------------------------ |
// TRANSPARENT_COLOR Register |
//------------------------------------------------ |
|
wire transparent_color_wr = (reg_access==REG_SET_TRANSPARENT) & (gpu_state==DATA1B_READ); |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) transparent_color <= 16'h0000; |
else if (transparent_color_wr) transparent_color <= gpu_data_i; |
|
assign cfg_transparent_color_o = transparent_color; |
|
endmodule // ogfx_gpu_reg |
|
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_undefines.v" |
`endif |
/trunk/core/rtl/verilog/ogfx_gpu.v
0,0 → 1,225
//---------------------------------------------------------------------------- |
// 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.v |
// |
// *Module Description: |
// Graphic-Processing unit of the graphic controller. |
// This block can perform the following hardware |
// accelerations: |
// |
// - |
// - |
// |
// *Author(s): |
// - Olivier Girard, olgirard@gmail.com |
// |
//---------------------------------------------------------------------------- |
// $Rev$ |
// $LastChangedBy$ |
// $LastChangedDate$ |
//---------------------------------------------------------------------------- |
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_defines.v" |
`endif |
|
module ogfx_gpu ( |
|
// OUTPUTs |
gpu_cmd_done_evt_o, // GPU command done event |
gpu_cmd_error_evt_o, // GPU command error event |
gpu_get_data_o, // GPU get next data |
|
vid_ram_addr_o, // Video-RAM address |
vid_ram_din_o, // Video-RAM data |
vid_ram_wen_o, // Video-RAM write strobe (active low) |
vid_ram_cen_o, // Video-RAM chip enable (active low) |
|
// INPUTs |
mclk, // Main system clock |
puc_rst, // Main system reset |
|
display_width_i, // Display width |
|
gfx_mode_i, // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp) |
|
gpu_data_i, // GPU data |
gpu_data_avail_i, // GPU data available |
gpu_enable_i, // GPU enable |
|
vid_ram_dout_i, // Video-RAM data input |
vid_ram_dout_rdy_nxt_i // Video-RAM data output ready during next cycle |
); |
|
// OUTPUTs |
//========= |
output gpu_cmd_done_evt_o; // GPU command done event |
output gpu_cmd_error_evt_o; // GPU command error event |
output gpu_get_data_o; // GPU get next data |
|
output [`VRAM_MSB:0] vid_ram_addr_o; // Video-RAM address |
output [15:0] vid_ram_din_o; // Video-RAM data |
output vid_ram_wen_o; // Video-RAM write strobe (active low) |
output vid_ram_cen_o; // Video-RAM chip enable (active low) |
|
// INPUTs |
//========= |
input mclk; // Main system clock |
input puc_rst; // Main system reset |
|
input [`LPIX_MSB:0] display_width_i; // Display width |
|
input [2:0] gfx_mode_i; // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp) |
|
input [15:0] gpu_data_i; // GPU data |
input gpu_data_avail_i; // GPU data available |
input gpu_enable_i; // GPU enable |
|
input [15:0] vid_ram_dout_i; // Video-RAM data input |
input vid_ram_dout_rdy_nxt_i; // Video-RAM data output ready during next cycle |
|
|
//============================================================================= |
// 1) WIRE, REGISTERS AND PARAMETER DECLARATION |
//============================================================================= |
|
wire exec_fill; |
wire exec_copy; |
wire exec_copy_trans; |
wire trig_exec; |
|
wire [`APIX_MSB:0] cfg_dst_px_addr; |
wire cfg_dst_cl_swp; |
wire cfg_dst_x_swp; |
wire cfg_dst_y_swp; |
wire [15:0] cfg_fill_color; |
wire [3:0] cfg_pix_op_sel; |
wire [`LPIX_MSB:0] cfg_rec_width; |
wire [`LPIX_MSB:0] cfg_rec_height; |
wire [`APIX_MSB:0] cfg_src_px_addr; |
wire cfg_src_cl_swp; |
wire cfg_src_x_swp; |
wire cfg_src_y_swp; |
wire [15:0] cfg_transparent_color; |
|
wire gpu_exec_done; |
|
|
//============================================================================= |
// 2) GPU CONGIGURATION & CONTROL REGISTERS |
//============================================================================= |
|
ogfx_gpu_reg ogfx_gpu_reg_inst ( |
|
// OUTPUTs |
.gpu_cmd_done_evt_o (gpu_cmd_done_evt_o ), // GPU command done event |
.gpu_cmd_error_evt_o (gpu_cmd_error_evt_o ), // GPU command error event |
.gpu_get_data_o (gpu_get_data_o ), // GPU get next data |
|
.exec_fill_o (exec_fill ), // Rectangle fill on going |
.exec_copy_o (exec_copy ), // Rectangle copy on going |
.exec_copy_trans_o (exec_copy_trans ), // Rectangle transparent copy on going |
.trig_exec_o (trig_exec ), // Trigger rectangle execution |
|
.cfg_dst_px_addr_o (cfg_dst_px_addr ), // Destination pixel address configuration |
.cfg_dst_cl_swp_o (cfg_dst_cl_swp ), // Destination Column/Line-Swap configuration |
.cfg_dst_x_swp_o (cfg_dst_x_swp ), // Destination X-Swap configuration |
.cfg_dst_y_swp_o (cfg_dst_y_swp ), // Destination Y-Swap configuration |
.cfg_fill_color_o (cfg_fill_color ), // Fill color (for rectangle fill operation) |
.cfg_pix_op_sel_o (cfg_pix_op_sel ), // Pixel operation to be performed during the copy |
.cfg_rec_width_o (cfg_rec_width ), // Rectangle width configuration |
.cfg_rec_height_o (cfg_rec_height ), // Rectangle height configuration |
.cfg_src_px_addr_o (cfg_src_px_addr ), // Source pixel address configuration |
.cfg_src_cl_swp_o (cfg_src_cl_swp ), // Source Column/Line-Swap configuration |
.cfg_src_x_swp_o (cfg_src_x_swp ), // Source X-Swap configuration |
.cfg_src_y_swp_o (cfg_src_y_swp ), // Source Y-Swap configuration |
.cfg_transparent_color_o (cfg_transparent_color ), // Transparent color (for rectangle transparent copy operation) |
|
|
// INPUTs |
.mclk (mclk ), // Main system clock |
.puc_rst (puc_rst ), // Main system reset |
|
.gpu_data_i (gpu_data_i ), // GPU data |
.gpu_data_avail_i (gpu_data_avail_i ), // GPU data available |
.gfx_mode_i (gfx_mode_i ), // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp) |
.gpu_enable_i (gpu_enable_i ), // GPU enable |
|
.gpu_exec_done_i (gpu_exec_done ) // GPU execution done |
); |
|
//============================================================================= |
// 3) 2D-DMA |
//============================================================================= |
|
ogfx_gpu_dma ogfx_gpu_dma_inst ( |
|
// OUTPUTs |
.gpu_exec_done_o (gpu_exec_done ), // GPU execution done |
|
.vid_ram_addr_o (vid_ram_addr_o ), // Video-RAM address |
.vid_ram_din_o (vid_ram_din_o ), // Video-RAM data |
.vid_ram_wen_o (vid_ram_wen_o ), // Video-RAM write strobe (active low) |
.vid_ram_cen_o (vid_ram_cen_o ), // Video-RAM chip enable (active low) |
|
// INPUTs |
.mclk (mclk ), // Main system clock |
.puc_rst (puc_rst ), // Main system reset |
|
.cfg_dst_px_addr_i (cfg_dst_px_addr ), // Destination pixel address configuration |
.cfg_dst_cl_swp_i (cfg_dst_cl_swp ), // Destination Column/Line-Swap configuration |
.cfg_dst_x_swp_i (cfg_dst_x_swp ), // Destination X-Swap configuration |
.cfg_dst_y_swp_i (cfg_dst_y_swp ), // Destination Y-Swap configuration |
.cfg_fill_color_i (cfg_fill_color ), // Fill color (for rectangle fill operation) |
.cfg_pix_op_sel_i (cfg_pix_op_sel ), // Pixel operation to be performed during the copy |
.cfg_rec_width_i (cfg_rec_width ), // Rectangle width configuration |
.cfg_rec_height_i (cfg_rec_height ), // Rectangle height configuration |
.cfg_src_px_addr_i (cfg_src_px_addr ), // Source pixel address configuration |
.cfg_src_cl_swp_i (cfg_src_cl_swp ), // Source Column/Line-Swap configuration |
.cfg_src_x_swp_i (cfg_src_x_swp ), // Source X-Swap configuration |
.cfg_src_y_swp_i (cfg_src_y_swp ), // Source Y-Swap configuration |
.cfg_transparent_color_i (cfg_transparent_color ), // Transparent color (for rectangle transparent copy operation) |
|
.display_width_i (display_width_i ), // Display width |
|
.gfx_mode_i (gfx_mode_i ), // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp) |
|
.gpu_enable_i (gpu_enable_i ), // GPU enable |
|
.exec_fill_i (exec_fill ), // Rectangle fill on going |
.exec_copy_i (exec_copy ), // Rectangle copy on going |
.exec_copy_trans_i (exec_copy_trans ), // Rectangle transparent copy on going |
.trig_exec_i (trig_exec ), // Trigger rectangle execution |
|
.vid_ram_dout_i (vid_ram_dout_i ), // Video-RAM data input |
.vid_ram_dout_rdy_nxt_i (vid_ram_dout_rdy_nxt_i) // Video-RAM data output ready during next cycle |
); |
|
endmodule // ogfx_gpu |
|
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_undefines.v" |
`endif |
/trunk/core/rtl/verilog/ogfx_reg_vram_addr.v
0,0 → 1,150
//---------------------------------------------------------------------------- |
// 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_calc_vram_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_reg_vram_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_msk_mode_i, // Video-RAM Mask mode enable |
vid_ram_win_mode_i, // Video-RAM Windows mode enable |
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_msk_mode_i; // Video-RAM Mask mode enable |
input vid_ram_win_mode_i; // Video-RAM Windows mode enable |
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) PARAMETER DECLARATION |
//============================================================================= |
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})); |
|
// Compute increment value depending on mask mode |
wire [`APIX_MSB:0] plus_one_val = {`APIX_MSB+1{gfx_mode_1_bpp_i & ~vid_ram_msk_mode_i}} & { {{`VRAM_MSB{1'b0}}, 1'b1}, 4'b0000} | |
{`APIX_MSB+1{gfx_mode_2_bpp_i & ~vid_ram_msk_mode_i}} & {1'b0, {{`VRAM_MSB{1'b0}}, 1'b1}, 3'b000 } | |
{`APIX_MSB+1{gfx_mode_4_bpp_i & ~vid_ram_msk_mode_i}} & {2'b00, {{`VRAM_MSB{1'b0}}, 1'b1}, 2'b00 } | |
{`APIX_MSB+1{gfx_mode_8_bpp_i & ~vid_ram_msk_mode_i}} & {3'b000, {{`VRAM_MSB{1'b0}}, 1'b1}, 1'b0 } | |
{`APIX_MSB+1{gfx_mode_16_bpp_i | vid_ram_msk_mode_i}} & {4'b0000, {{`VRAM_MSB{1'b0}}, 1'b1} } ; |
|
// Mux between initialization value and display width |
wire [`LPIX_MSB:0] vid_ram_width_mux = vid_ram_addr_init_i ? vid_ram_width_i : display_width_i ; |
|
// Zero extension for LINT cleanup |
wire [`APIX_MSB*3:0] vid_ram_width_norm = {{`APIX_MSB*3-`LPIX_MSB{1'b0}}, vid_ram_width_mux}; |
|
// Select base address for next calculation |
wire [`APIX_MSB:0] next_base_addr = (vid_ram_addr_init_i | ~vid_ram_line_done | ~vid_ram_win_mode_i) ? vid_ram_addr_i : |
vid_ram_line_addr ; |
// Compute next address |
wire [`APIX_MSB:0] next_addr = next_base_addr |
+ (vid_ram_width_norm[`APIX_MSB:0] & {`APIX_MSB+1{(~vid_ram_addr_init_i & vid_ram_win_mode_i) ? (~vid_ram_win_y_swap_i & (vid_ram_win_cl_swap_i ^ vid_ram_line_done)) : 1'b0}}) |
- (vid_ram_width_norm[`APIX_MSB:0] & {`APIX_MSB+1{(~vid_ram_addr_init_i & vid_ram_win_mode_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_mode_i) ? (~vid_ram_win_x_swap_i & ~(vid_ram_win_cl_swap_i ^ vid_ram_line_done)) : (~vid_ram_win_mode_i & ~vid_ram_addr_init_i)}}) |
- (plus_one_val & {`APIX_MSB+1{(~vid_ram_addr_init_i & vid_ram_win_mode_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) & vid_ram_win_mode_i; |
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 |
wire [`APIX_MSB:0] 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-5{1'b0}}, plus_one_val[4:0]}; |
|
|
endmodule // ogfx_reg_vram_addr |
|
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_undefines.v" |
`endif |
/trunk/core/rtl/verilog/ogfx_if_lt24.v
0,0 → 1,471
//---------------------------------------------------------------------------- |
// 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_if_lt24.v |
// |
// *Module Description: |
// Interface to the LT24 LCD display. |
// |
// *Author(s): |
// - Olivier Girard, olgirard@gmail.com |
// |
//---------------------------------------------------------------------------- |
// $Rev$ |
// $LastChangedBy$ |
// $LastChangedDate$ |
//---------------------------------------------------------------------------- |
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_defines.v" |
`endif |
|
module ogfx_if_lt24 ( |
|
// OUTPUTs |
event_fsm_done_o, // Event - FSM is done |
event_fsm_start_o, // Event - FSM is starting |
|
lt24_cs_n_o, // LT24 Chip select (Active low) |
lt24_d_o, // LT24 Data output |
lt24_d_en_o, // LT24 Data output enable |
lt24_rd_n_o, // LT24 Read strobe (Active low) |
lt24_rs_o, // LT24 Command/Param selection (Cmd=0/Param=1) |
lt24_wr_n_o, // LT24 Write strobe (Active low) |
|
refresh_active_o, // Display refresh on going |
refresh_data_request_o, // Display refresh new data request |
|
status_o, // Status - FSM |
|
// INPUTs |
mclk, // Main system clock |
puc_rst, // Main system reset |
|
cfg_lt24_clk_div_i, // Clock Divider configuration for LT24 interface |
cfg_lt24_display_size_i, // Display size (number of pixels) |
cfg_lt24_refresh_i, // Refresh rate configuration for LT24 interface |
cfg_lt24_refresh_sync_en_i, // Refresh sync enable configuration for LT24 interface |
cfg_lt24_refresh_sync_val_i, // Refresh sync value configuration for LT24 interface |
|
cmd_dfill_i, // Display refresh data |
cmd_dfill_trig_i, // Trigger a full display refresh |
|
cmd_generic_cmd_val_i, // Generic command value |
cmd_generic_has_param_i, // Generic command to be sent has parameter(s) |
cmd_generic_param_val_i, // Generic command parameter value |
cmd_generic_trig_i, // Trigger generic command transmit (or new parameter available) |
|
cmd_refresh_i, // Display refresh command |
|
lt24_d_i, // LT24 Data input |
|
refresh_data_i, // Display refresh data |
refresh_data_ready_i // Display refresh new data is ready |
); |
|
// OUTPUTs |
//========= |
output event_fsm_done_o; // LT24 FSM done event |
output event_fsm_start_o; // LT24 FSM start event |
|
output lt24_cs_n_o; // LT24 Chip select (Active low) |
output [15:0] lt24_d_o; // LT24 Data output |
output lt24_d_en_o; // LT24 Data output enable |
output lt24_rd_n_o; // LT24 Read strobe (Active low) |
output lt24_rs_o; // LT24 Command/Param selection (Cmd=0/Param=1) |
output lt24_wr_n_o; // LT24 Write strobe (Active low) |
|
output refresh_active_o; // Display refresh on going |
output refresh_data_request_o; // Display refresh new data request |
|
output [4:0] status_o; // LT24 FSM Status |
|
// INPUTs |
//========= |
input mclk; // Main system clock |
input puc_rst; // Main system reset |
|
input [2:0] cfg_lt24_clk_div_i; // Clock Divider configuration for LT24 interface |
input [`SPIX_MSB:0] cfg_lt24_display_size_i; // Display size (number of pixels) |
input [11:0] cfg_lt24_refresh_i; // Refresh rate configuration for LT24 interface |
input cfg_lt24_refresh_sync_en_i; // Refresh sync enable configuration for LT24 interface |
input [9:0] cfg_lt24_refresh_sync_val_i; // Refresh sync value configuration for LT24 interface |
|
input [15:0] cmd_dfill_i; // Display refresh data |
input cmd_dfill_trig_i; // Trigger a full display refresh |
|
input [7:0] cmd_generic_cmd_val_i; // Generic command value |
input cmd_generic_has_param_i; // Generic command to be sent has parameter(s) |
input [15:0] cmd_generic_param_val_i; // Generic command parameter value |
input cmd_generic_trig_i; // Trigger generic command transmit (or new parameter available) |
|
input cmd_refresh_i; // Display refresh command |
|
input [15:0] lt24_d_i; // LT24 Data input |
|
input [15:0] refresh_data_i; // Display refresh data |
input refresh_data_ready_i; // Display refresh new data is ready |
|
|
//============================================================================= |
// 1) WIRE, REGISTERS AND PARAMETER DECLARATION |
//============================================================================= |
|
// State machine registers |
reg [4:0] lt24_state; |
reg [4:0] lt24_state_nxt; |
|
// Others |
reg refresh_trigger; |
wire status_gts_match; |
|
// State definition |
parameter STATE_IDLE = 0, // IDLE state |
|
STATE_CMD_LO = 1, // Generic command to LT24 |
STATE_CMD_HI = 2, |
STATE_CMD_PARAM_LO = 3, |
STATE_CMD_PARAM_HI = 4, |
STATE_CMD_PARAM_WAIT = 5, |
|
STATE_RAMWR_INIT_CMD_LO = 6, // Initialize display buffer with data |
STATE_RAMWR_INIT_CMD_HI = 7, |
STATE_RAMWR_INIT_DATA_LO = 8, |
STATE_RAMWR_INIT_DATA_HI = 9, |
|
STATE_SCANLINE_CMD_LO = 10, // Wait for right scanline |
STATE_SCANLINE_CMD_HI = 11, |
STATE_SCANLINE_DUMMY_LO = 12, |
STATE_SCANLINE_DUMMY_HI = 13, |
STATE_SCANLINE_GTS1_LO = 14, |
STATE_SCANLINE_GTS1_HI = 15, |
STATE_SCANLINE_GTS2_LO = 16, |
STATE_SCANLINE_GTS2_HI = 17, |
|
|
STATE_RAMWR_REFR_CMD_LO = 18, // Refresh display buffer |
STATE_RAMWR_REFR_CMD_HI = 19, |
STATE_RAMWR_REFR_WAIT = 20, |
STATE_RAMWR_REFR_DATA_LO = 21, |
STATE_RAMWR_REFR_DATA_HI = 22; |
|
|
//============================================================================ |
// 5) STATE MACHINE SENDING IMAGE DATA TO A SPECIFIED DISPLAY |
//============================================================================ |
|
//-------------------------------- |
// LT24 Controller Clock Timer |
//-------------------------------- |
reg [3:0] lt24_timer; |
|
wire lt24_timer_done = lt24_d_en_o ? (lt24_timer == {1'b0, cfg_lt24_clk_div_i}) : |
(lt24_timer == {cfg_lt24_clk_div_i, 1'b0}) ; // Use slower timing for read accesses |
|
wire lt24_timer_run = (lt24_state != STATE_IDLE) & |
(lt24_state != STATE_CMD_PARAM_WAIT) & |
(lt24_state != STATE_RAMWR_REFR_WAIT) & |
~lt24_timer_done; |
|
wire lt24_timer_init = (lt24_timer_done & // Init if counter reaches limit: |
!((lt24_state == STATE_CMD_PARAM_HI) & cmd_generic_has_param_i) & // -> if not moving to STATE_CMD_PARAM_WAIT |
!((lt24_state == STATE_CMD_PARAM_WAIT))) | // -> if not in STATE_CMD_PARAM_WAIT |
((lt24_state == STATE_CMD_PARAM_WAIT) & (cmd_generic_trig_i | ~cmd_generic_has_param_i)); // Init when leaving the STATE_CMD_PARAM_WAIT state |
|
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) lt24_timer <= 4'h0; |
else if (lt24_timer_init) lt24_timer <= 4'h0; |
else if (lt24_timer_run) lt24_timer <= lt24_timer+4'h1; |
|
|
//-------------------------------- |
// Pixel counter |
//-------------------------------- |
reg [`SPIX_MSB:0] lt24_pixel_cnt; |
|
wire lt24_pixel_cnt_run = (lt24_state==STATE_RAMWR_INIT_DATA_HI) | |
(lt24_state==STATE_RAMWR_REFR_DATA_HI); |
|
wire lt24_pixel_cnt_done = (lt24_pixel_cnt==1) | (lt24_pixel_cnt==0); |
|
wire lt24_pixel_cnt_init = (lt24_state==STATE_RAMWR_INIT_CMD_HI) | |
(lt24_state==STATE_RAMWR_REFR_CMD_HI) | |
(lt24_pixel_cnt_done & lt24_pixel_cnt_run); |
|
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) lt24_pixel_cnt <= {`SPIX_MSB+1{1'h0}}; |
else if (lt24_timer_init) |
begin |
if (lt24_pixel_cnt_init) lt24_pixel_cnt <= cfg_lt24_display_size_i; |
else if (lt24_pixel_cnt_run) lt24_pixel_cnt <= lt24_pixel_cnt-{{`SPIX_MSB{1'h0}},1'b1}; |
end |
|
|
//-------------------------------- |
// States Transitions |
//-------------------------------- |
always @(lt24_state or cmd_dfill_trig_i or cmd_generic_trig_i or refresh_trigger or cfg_lt24_refresh_sync_en_i or status_gts_match or refresh_data_request_o or cmd_generic_has_param_i or lt24_timer_done or lt24_pixel_cnt_done) |
case(lt24_state) |
STATE_IDLE : lt24_state_nxt = cmd_dfill_trig_i ? STATE_RAMWR_INIT_CMD_LO : |
refresh_trigger ? |
(cfg_lt24_refresh_sync_en_i ? STATE_SCANLINE_CMD_LO : STATE_RAMWR_REFR_CMD_LO) : |
cmd_generic_trig_i ? STATE_CMD_LO : STATE_IDLE ; |
|
// GENERIC COMMANDS |
STATE_CMD_LO : lt24_state_nxt = ~lt24_timer_done ? STATE_CMD_LO : STATE_CMD_HI ; |
STATE_CMD_HI : lt24_state_nxt = ~lt24_timer_done ? STATE_CMD_HI : |
cmd_generic_has_param_i ? STATE_CMD_PARAM_LO : STATE_IDLE ; |
|
STATE_CMD_PARAM_LO : lt24_state_nxt = ~lt24_timer_done ? STATE_CMD_PARAM_LO : STATE_CMD_PARAM_HI ; |
STATE_CMD_PARAM_HI : lt24_state_nxt = ~lt24_timer_done ? STATE_CMD_PARAM_HI : |
cmd_generic_has_param_i ? STATE_CMD_PARAM_WAIT : STATE_IDLE ; |
|
STATE_CMD_PARAM_WAIT : lt24_state_nxt = cmd_generic_trig_i ? STATE_CMD_PARAM_LO : |
cmd_generic_has_param_i ? STATE_CMD_PARAM_WAIT : STATE_IDLE ; |
|
// MEMORY INITIALIZATION |
STATE_RAMWR_INIT_CMD_LO : lt24_state_nxt = ~lt24_timer_done ? STATE_RAMWR_INIT_CMD_LO : STATE_RAMWR_INIT_CMD_HI ; |
STATE_RAMWR_INIT_CMD_HI : lt24_state_nxt = ~lt24_timer_done ? STATE_RAMWR_INIT_CMD_HI : STATE_RAMWR_INIT_DATA_LO ; |
|
STATE_RAMWR_INIT_DATA_LO : lt24_state_nxt = ~lt24_timer_done ? STATE_RAMWR_INIT_DATA_LO : STATE_RAMWR_INIT_DATA_HI ; |
STATE_RAMWR_INIT_DATA_HI : lt24_state_nxt = lt24_timer_done & |
lt24_pixel_cnt_done ? STATE_IDLE : |
~lt24_timer_done ? STATE_RAMWR_INIT_DATA_HI : STATE_RAMWR_INIT_DATA_LO ; |
|
// WAIT FOR RIGHT SCANLINE BEFORE REFRESH |
STATE_SCANLINE_CMD_LO : lt24_state_nxt = ~lt24_timer_done ? STATE_SCANLINE_CMD_LO : STATE_SCANLINE_CMD_HI ; |
STATE_SCANLINE_CMD_HI : lt24_state_nxt = ~lt24_timer_done ? STATE_SCANLINE_CMD_HI : STATE_SCANLINE_DUMMY_LO ; |
|
STATE_SCANLINE_DUMMY_LO : lt24_state_nxt = ~lt24_timer_done ? STATE_SCANLINE_DUMMY_LO : STATE_SCANLINE_DUMMY_HI ; |
STATE_SCANLINE_DUMMY_HI : lt24_state_nxt = ~lt24_timer_done ? STATE_SCANLINE_DUMMY_HI : STATE_SCANLINE_GTS1_LO ; |
|
STATE_SCANLINE_GTS1_LO : lt24_state_nxt = ~lt24_timer_done ? STATE_SCANLINE_GTS1_LO : STATE_SCANLINE_GTS1_HI ; |
STATE_SCANLINE_GTS1_HI : lt24_state_nxt = ~lt24_timer_done ? STATE_SCANLINE_GTS1_HI : STATE_SCANLINE_GTS2_LO ; |
|
STATE_SCANLINE_GTS2_LO : lt24_state_nxt = ~lt24_timer_done ? STATE_SCANLINE_GTS2_LO : STATE_SCANLINE_GTS2_HI ; |
STATE_SCANLINE_GTS2_HI : lt24_state_nxt = ~lt24_timer_done ? STATE_SCANLINE_GTS2_HI : |
(status_gts_match | |
~cfg_lt24_refresh_sync_en_i) ? STATE_RAMWR_REFR_CMD_LO : STATE_SCANLINE_CMD_LO ; |
|
// FRAME REFRESH |
STATE_RAMWR_REFR_CMD_LO : lt24_state_nxt = ~lt24_timer_done ? STATE_RAMWR_REFR_CMD_LO : STATE_RAMWR_REFR_CMD_HI ; |
STATE_RAMWR_REFR_CMD_HI : lt24_state_nxt = ~lt24_timer_done ? STATE_RAMWR_REFR_CMD_HI : |
~refresh_data_request_o ? STATE_RAMWR_REFR_DATA_LO : STATE_RAMWR_REFR_WAIT ; |
|
STATE_RAMWR_REFR_WAIT : lt24_state_nxt = ~refresh_data_request_o ? STATE_RAMWR_REFR_DATA_LO : STATE_RAMWR_REFR_WAIT ; |
|
STATE_RAMWR_REFR_DATA_LO : lt24_state_nxt = ~lt24_timer_done ? STATE_RAMWR_REFR_DATA_LO : STATE_RAMWR_REFR_DATA_HI ; |
STATE_RAMWR_REFR_DATA_HI : lt24_state_nxt = lt24_timer_done & |
lt24_pixel_cnt_done ? STATE_IDLE : |
~lt24_timer_done ? STATE_RAMWR_REFR_DATA_HI : |
~refresh_data_request_o ? STATE_RAMWR_REFR_DATA_LO : STATE_RAMWR_REFR_WAIT ; |
|
// pragma coverage off |
default : lt24_state_nxt = STATE_IDLE; |
// pragma coverage on |
endcase |
|
// State machine |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) lt24_state <= STATE_IDLE; |
else lt24_state <= lt24_state_nxt; |
|
|
// Output status |
assign status_o[0] = (lt24_state != STATE_IDLE); // LT24 FSM BUSY |
|
assign status_o[1] = (lt24_state == STATE_CMD_PARAM_WAIT); // LT24 Waits for command parameter |
|
assign status_o[2] = (lt24_state == STATE_RAMWR_REFR_CMD_LO) | (lt24_state == STATE_RAMWR_REFR_CMD_HI) | // LT24 REFRESH BUSY |
(lt24_state == STATE_RAMWR_REFR_DATA_LO) | (lt24_state == STATE_RAMWR_REFR_DATA_HI) | |
(lt24_state == STATE_RAMWR_REFR_WAIT); |
|
assign status_o[3] = (lt24_state == STATE_SCANLINE_CMD_LO) | (lt24_state == STATE_SCANLINE_CMD_HI) | // LT24 WAIT FOR SCANLINE |
(lt24_state == STATE_SCANLINE_DUMMY_LO) | (lt24_state == STATE_SCANLINE_DUMMY_HI) | |
(lt24_state == STATE_SCANLINE_GTS1_LO) | (lt24_state == STATE_SCANLINE_GTS1_HI) | |
(lt24_state == STATE_SCANLINE_GTS2_LO) | (lt24_state == STATE_SCANLINE_GTS2_HI); |
|
assign status_o[4] = (lt24_state == STATE_RAMWR_INIT_CMD_LO) | (lt24_state == STATE_RAMWR_INIT_CMD_HI) | // LT24 INIT BUSY |
(lt24_state == STATE_RAMWR_INIT_DATA_LO) | (lt24_state == STATE_RAMWR_INIT_DATA_HI); |
|
assign refresh_active_o = status_o[2]; |
|
|
// Refresh data request |
wire refresh_data_request_set = ((lt24_state == STATE_RAMWR_REFR_CMD_LO) & (lt24_state_nxt == STATE_RAMWR_REFR_CMD_HI)) | |
((lt24_state == STATE_RAMWR_REFR_DATA_LO) & (lt24_state_nxt == STATE_RAMWR_REFR_DATA_HI)) | |
(lt24_state == STATE_RAMWR_REFR_WAIT); |
wire refresh_data_request_clr = refresh_data_ready_i; |
reg refresh_data_request_reg; |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) refresh_data_request_reg <= 1'b0; |
else refresh_data_request_reg <= refresh_data_request_clr ? 1'b0 : |
refresh_data_request_set ? 1'b1 : refresh_data_request_reg; |
|
assign refresh_data_request_o = refresh_data_request_reg & ~refresh_data_ready_i; |
|
assign event_fsm_start_o = (lt24_state_nxt != STATE_IDLE) & (lt24_state == STATE_IDLE); |
assign event_fsm_done_o = (lt24_state != STATE_IDLE) & (lt24_state_nxt == STATE_IDLE); |
|
|
//============================================================================ |
// 6) LT24 CONTROLLER OUTPUT ASSIGNMENT |
//============================================================================ |
|
// LT24 Chip select (active low) |
reg lt24_cs_n_o; |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) lt24_cs_n_o <= 1'b1; |
else lt24_cs_n_o <= (lt24_state_nxt==STATE_IDLE); |
|
// Command (0) or Data (1) |
reg lt24_rs_o; |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) lt24_rs_o <= 1'b1; |
else lt24_rs_o <= ~((lt24_state_nxt==STATE_CMD_LO) | (lt24_state_nxt==STATE_CMD_HI) | |
(lt24_state_nxt==STATE_SCANLINE_CMD_LO) | (lt24_state_nxt==STATE_SCANLINE_CMD_HI) | |
(lt24_state_nxt==STATE_RAMWR_INIT_CMD_LO) | (lt24_state_nxt==STATE_RAMWR_INIT_CMD_HI) | |
(lt24_state_nxt==STATE_RAMWR_REFR_CMD_LO) | (lt24_state_nxt==STATE_RAMWR_REFR_CMD_HI)); |
|
// LT24 Write strobe (Active low) |
reg lt24_wr_n_o; |
|
wire lt24_wr_n_clr = (lt24_state_nxt==STATE_CMD_LO) | (lt24_state_nxt==STATE_CMD_PARAM_LO) | (lt24_state_nxt==STATE_SCANLINE_CMD_LO) | |
(lt24_state_nxt==STATE_RAMWR_INIT_CMD_LO) | (lt24_state_nxt==STATE_RAMWR_INIT_DATA_LO) | |
(lt24_state_nxt==STATE_RAMWR_REFR_CMD_LO) | (lt24_state_nxt==STATE_RAMWR_REFR_DATA_LO); |
|
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) lt24_wr_n_o <= 1'b1; |
else if (lt24_wr_n_clr) lt24_wr_n_o <= 1'b0; |
else lt24_wr_n_o <= 1'b1; |
|
// LT24 Read strobe (active low) |
reg lt24_rd_n_o; |
|
wire lt24_rd_n_clr = (lt24_state_nxt==STATE_SCANLINE_DUMMY_LO) | |
(lt24_state_nxt==STATE_SCANLINE_GTS1_LO) | (lt24_state_nxt==STATE_SCANLINE_GTS2_LO); |
|
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) lt24_rd_n_o <= 1'b1; |
else if (lt24_rd_n_clr) lt24_rd_n_o <= 1'b0; |
else lt24_rd_n_o <= 1'b1; |
|
|
// LT24 Data |
reg [15:0] lt24_d_nxt; |
always @(lt24_state_nxt or cmd_generic_cmd_val_i or cmd_generic_param_val_i or lt24_d_o or cmd_dfill_i or refresh_data_i) |
case(lt24_state_nxt) |
STATE_IDLE : lt24_d_nxt <= 16'h0000; |
|
STATE_CMD_LO, |
STATE_CMD_HI : lt24_d_nxt <= {8'h00, cmd_generic_cmd_val_i}; |
STATE_CMD_PARAM_LO, |
STATE_CMD_PARAM_HI : lt24_d_nxt <= cmd_generic_param_val_i; |
STATE_CMD_PARAM_WAIT : lt24_d_nxt <= lt24_d_o; |
|
STATE_RAMWR_INIT_CMD_LO, |
STATE_RAMWR_INIT_CMD_HI : lt24_d_nxt <= 16'h002C; |
STATE_RAMWR_INIT_DATA_LO, |
STATE_RAMWR_INIT_DATA_HI : lt24_d_nxt <= cmd_dfill_i; |
|
STATE_SCANLINE_CMD_LO, |
STATE_SCANLINE_CMD_HI : lt24_d_nxt <= 16'h0045; |
|
STATE_RAMWR_REFR_CMD_LO, |
STATE_RAMWR_REFR_CMD_HI : lt24_d_nxt <= 16'h002C; |
STATE_RAMWR_REFR_DATA_LO : lt24_d_nxt <= refresh_data_i; |
STATE_RAMWR_REFR_DATA_HI : lt24_d_nxt <= lt24_d_o; |
STATE_RAMWR_REFR_WAIT : lt24_d_nxt <= lt24_d_o; |
|
// pragma coverage off |
default : lt24_d_nxt <= 16'h0000; |
// pragma coverage on |
endcase |
|
reg [15:0] lt24_d_o; |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) lt24_d_o <= 16'h0000; |
else lt24_d_o <= lt24_d_nxt; |
|
// Output enable |
reg lt24_d_en_o; |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) lt24_d_en_o <= 1'h0; // Don't drive output during reset |
else lt24_d_en_o <= ~((lt24_state_nxt == STATE_SCANLINE_DUMMY_LO) | |
(lt24_state_nxt == STATE_SCANLINE_DUMMY_HI) | |
(lt24_state_nxt == STATE_SCANLINE_GTS1_LO ) | |
(lt24_state_nxt == STATE_SCANLINE_GTS1_HI ) | |
(lt24_state_nxt == STATE_SCANLINE_GTS2_LO ) | |
(lt24_state_nxt == STATE_SCANLINE_GTS2_HI )); |
|
//============================================================================ |
// 7) LT24 GTS VALUE (i.e. CURRENT SCAN LINE) |
//============================================================================ |
|
reg [1:0] status_gts_msb; |
wire status_gts_msb_wr = ((lt24_state == STATE_SCANLINE_GTS1_LO) & (lt24_state_nxt == STATE_SCANLINE_GTS1_HI)); |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) status_gts_msb <= 2'h0; |
else if (status_gts_msb_wr) status_gts_msb <= lt24_d_i[1:0]; |
|
reg [7:0] status_gts_lsb; |
wire status_gts_lsb_wr = ((lt24_state == STATE_SCANLINE_GTS2_LO) & (lt24_state_nxt == STATE_SCANLINE_GTS2_HI)); |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) status_gts_lsb <= 8'h00; |
else if (status_gts_lsb_wr) status_gts_lsb <= lt24_d_i[7:0]; |
|
wire [9:0] status_gts = {status_gts_msb, status_gts_lsb}; |
|
assign status_gts_match = (status_gts == cfg_lt24_refresh_sync_val_i); |
|
//============================================================================ |
// 8) REFRESH TIMER & TRIGGER |
//============================================================================ |
|
// Refresh Timer |
reg [23:0] refresh_timer; |
wire refresh_timer_disable = (cfg_lt24_refresh_i==12'h000) | ~cmd_refresh_i; |
wire refresh_timer_done = (refresh_timer[23:12]==cfg_lt24_refresh_i); |
|
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) refresh_timer <= 24'h000000; |
else if (refresh_timer_disable) refresh_timer <= 24'h000000; |
else if (refresh_timer_done) refresh_timer <= 24'h000000; |
else refresh_timer <= refresh_timer + 24'h1; |
|
// Refresh Trigger |
wire refresh_trigger_set = (lt24_state==STATE_IDLE) & cmd_refresh_i & (refresh_timer==24'h000000); |
wire refresh_trigger_clr = (lt24_state==STATE_RAMWR_REFR_CMD_LO); |
|
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) refresh_trigger <= 1'b0; |
else if (refresh_trigger_set) refresh_trigger <= 1'b1; |
else if (refresh_trigger_clr) refresh_trigger <= 1'b0; |
|
endmodule // ogfx_if_lt24 |
|
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_undefines.v" |
`endif |
/trunk/core/rtl/verilog/ogfx_backend_frame_fifo.v
0,0 → 1,398
//---------------------------------------------------------------------------- |
// 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_backend_frame_fifo.v |
// |
// *Module Description: |
// Mini-cache memory for frame memory access. |
// |
// *Author(s): |
// - Olivier Girard, olgirard@gmail.com |
// |
//---------------------------------------------------------------------------- |
// $Rev$ |
// $LastChangedBy$ |
// $LastChangedDate$ |
//---------------------------------------------------------------------------- |
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_defines.v" |
`endif |
|
module ogfx_backend_frame_fifo ( |
|
// OUTPUTs |
frame_data_o, // Frame data |
frame_data_ready_o, // Frame data ready |
|
vid_ram_addr_o, // Video-RAM address |
vid_ram_cen_o, // Video-RAM enable (active low) |
|
// INPUTs |
mclk, // Main system clock |
puc_rst, // Main system reset |
|
display_width_i, // Display width |
display_height_i, // Display height |
display_size_i, // Display size (number of pixels) |
display_y_swap_i, // Display configuration: swap Y axis (horizontal symmetry) |
display_x_swap_i, // Display configuration: swap X axis (vertical symmetry) |
display_cl_swap_i, // Display configuration: swap column/lines |
|
frame_data_request_i, // Request for next frame data |
|
gfx_mode_i, // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp) |
|
vid_ram_dout_i, // Video-RAM data output |
vid_ram_dout_rdy_nxt_i, // Video-RAM data output ready during next cycle |
|
refresh_active_i, // Display refresh on going |
refresh_frame_base_addr_i // Refresh frame base address |
); |
|
// OUTPUTs |
//========= |
output [15:0] frame_data_o; // Frame data |
output frame_data_ready_o; // Frame data ready |
|
output[`VRAM_MSB:0] vid_ram_addr_o; // Video-RAM address |
output vid_ram_cen_o; // Video-RAM enable (active low) |
|
// INPUTs |
//========= |
input mclk; // Main system clock |
input puc_rst; // Main system reset |
|
input [`LPIX_MSB:0] display_width_i; // Display width |
input [`LPIX_MSB:0] display_height_i; // Display height |
input [`SPIX_MSB:0] display_size_i; // Display size (number of pixels) |
input display_y_swap_i; // Display configuration: swap Y axis (horizontal symmetry) |
input display_x_swap_i; // Display configuration: swap X axis (vertical symmetry) |
input display_cl_swap_i; // Display configuration: swap column/lines |
|
input frame_data_request_i; // Request for next frame data |
|
input [2:0] gfx_mode_i; // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp) |
|
input [15:0] vid_ram_dout_i; // Video-RAM data output |
input vid_ram_dout_rdy_nxt_i; // Video-RAM data output ready during next cycle |
|
input refresh_active_i; // Display refresh on going |
input [`APIX_MSB:0] refresh_frame_base_addr_i; // Refresh frame base address |
|
|
//============================================================================= |
// 1) WIRE, REGISTERS AND PARAMETER DECLARATION |
//============================================================================= |
|
// Some parameter(s) |
parameter FIFO_EMPTY = 2'h0, |
FIFO_FULL = 2'h3; |
|
// Video modes decoding |
wire gfx_mode_1_bpp = (gfx_mode_i == 3'b000); |
wire gfx_mode_2_bpp = (gfx_mode_i == 3'b001); |
wire gfx_mode_4_bpp = (gfx_mode_i == 3'b010); |
wire gfx_mode_8_bpp = (gfx_mode_i == 3'b011); |
wire gfx_mode_16_bpp = ~(gfx_mode_8_bpp | gfx_mode_4_bpp | |
gfx_mode_2_bpp | gfx_mode_1_bpp); |
|
// Others |
reg [1:0] fifo_counter; |
wire [1:0] fifo_counter_nxt; |
wire fifo_data_ready; |
wire read_from_fifo; |
reg vid_ram_data_mux_ready; |
reg vid_ram_dout_ready; |
wire [15:0] vid_ram_dout_processed; |
|
|
//============================================================================ |
// 1) FRAME ADDRESS GENERATION |
//============================================================================ |
|
//-------------------------------- |
// FIFO data request |
//-------------------------------- |
// The FIFO requests for new data whenever it is not full (or not about to get full) |
|
reg fifo_data_request; |
wire fifo_data_request_nxt = refresh_active_i & |
(fifo_counter_nxt != FIFO_FULL) & // FIFO is full |
~((fifo_counter_nxt == (FIFO_FULL-1)) & fifo_data_ready); // FIFO is about to be full |
|
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) fifo_data_request <= 1'h0; |
else fifo_data_request <= fifo_data_request_nxt; |
|
//-------------------------------- |
// Video RAM Address generation |
//-------------------------------- |
reg [`APIX_MSB:0] vid_ram_pixel_addr; |
reg [`APIX_MSB:0] vid_ram_line_addr; |
reg [`LPIX_MSB:0] vid_ram_column_count; |
|
// Detect when the fifo is done reading the current pixel data |
wire vid_ram_pixel_done = fifo_data_request & fifo_data_ready; |
|
// Detect when the current line refresh is done |
wire [`LPIX_MSB:0] line_length = display_cl_swap_i ? display_height_i : display_width_i; |
wire vid_ram_line_done = vid_ram_pixel_done & (vid_ram_column_count==(line_length-{{`LPIX_MSB{1'b0}}, 1'b1})); |
|
// Zero extension for LINT cleanup |
wire [`VRAM_MSB*3:0] display_size_norm = {{`VRAM_MSB*3-`SPIX_MSB{1'b0}}, display_size_i}; |
wire [`VRAM_MSB*3:0] display_width_norm = {{`VRAM_MSB*3-`LPIX_MSB{1'b0}}, display_width_i}; |
|
// Based on the display configuration (i.e. X-Swap / Y-Swap / CL-Swap) |
// the screen is not going to be refreshed in the same way. |
// The screen refresh is the performed according to the following |
// pseudo-code procedure: |
// |
// for (l_idx=0; l_idx<HEIGHT; l_idx++) |
// for (c_idx=0; c_idx<WIDTH; c_idx++) |
// addr = FIRST + 0 + WIDTH*l_idx + c_idx // Normal |
// addr = FIRST + WIDTH-1 + WIDTH*l_idx - c_idx // X-Swap |
// addr = LAST - WIDTH+1 - WIDTH*l_idx + c_idx // Y-Swap |
// addr = LAST - 0 - WIDTH*l_idx - c_idx // X/Y-Swap |
// |
|
wire [`APIX_MSB:0] next_base_addr = ~refresh_active_i ? refresh_frame_base_addr_i : |
vid_ram_line_done ? vid_ram_line_addr : |
vid_ram_pixel_addr ; |
|
wire [`APIX_MSB:0] next_addr = next_base_addr |
+ (display_size_norm[`APIX_MSB:0] & {`APIX_MSB+1{refresh_active_i ? 1'b0 : display_y_swap_i}}) |
+ (display_width_norm[`APIX_MSB:0] & {`APIX_MSB+1{refresh_active_i ? (~display_y_swap_i & (display_cl_swap_i ^ vid_ram_line_done)) : display_x_swap_i}}) |
- (display_width_norm[`APIX_MSB:0] & {`APIX_MSB+1{refresh_active_i ? ( display_y_swap_i & (display_cl_swap_i ^ vid_ram_line_done)) : display_y_swap_i}}) |
+ ({{`APIX_MSB{1'b0}}, 1'b1} & {`APIX_MSB+1{refresh_active_i ? (~display_x_swap_i & ~(display_cl_swap_i ^ vid_ram_line_done)) : 1'b0 }}) |
- ({{`APIX_MSB{1'b0}}, 1'b1} & {`APIX_MSB+1{refresh_active_i ? ( display_x_swap_i & ~(display_cl_swap_i ^ vid_ram_line_done)) : display_x_swap_i}}); |
|
wire update_line_addr = ~refresh_active_i | vid_ram_line_done; |
wire update_pixel_addr = update_line_addr | vid_ram_pixel_done; |
|
// 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 |
wire [`APIX_MSB:0] vid_ram_pixel_addr_nxt = update_pixel_addr ? next_addr : vid_ram_pixel_addr; |
|
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) vid_ram_pixel_addr <= {`APIX_MSB+1{1'b0}}; |
else vid_ram_pixel_addr <= vid_ram_pixel_addr_nxt; |
|
// 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 (~refresh_active_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_pixel_done) vid_ram_column_count <= vid_ram_column_count + {{`LPIX_MSB{1'b0}}, 1'b1}; |
|
// Depending on the color mode, format the address for doing the RAM accesses. |
assign vid_ram_addr_o = ({`VRAM_MSB+1{gfx_mode_1_bpp }} & vid_ram_pixel_addr[`VRAM_MSB+4:4]) | |
({`VRAM_MSB+1{gfx_mode_2_bpp }} & vid_ram_pixel_addr[`VRAM_MSB+3:3]) | |
({`VRAM_MSB+1{gfx_mode_4_bpp }} & vid_ram_pixel_addr[`VRAM_MSB+2:2]) | |
({`VRAM_MSB+1{gfx_mode_8_bpp }} & vid_ram_pixel_addr[`VRAM_MSB+1:1]) | |
({`VRAM_MSB+1{gfx_mode_16_bpp}} & vid_ram_pixel_addr[`VRAM_MSB+0:0]) ; |
|
// Compute the next RAM address to detect when a new address is generated |
wire [16:0] vid_ram_addr_nxt = ({`VRAM_MSB+1{gfx_mode_1_bpp }} & vid_ram_pixel_addr_nxt[`VRAM_MSB+4:4]) | |
({`VRAM_MSB+1{gfx_mode_2_bpp }} & vid_ram_pixel_addr_nxt[`VRAM_MSB+3:3]) | |
({`VRAM_MSB+1{gfx_mode_4_bpp }} & vid_ram_pixel_addr_nxt[`VRAM_MSB+2:2]) | |
({`VRAM_MSB+1{gfx_mode_8_bpp }} & vid_ram_pixel_addr_nxt[`VRAM_MSB+1:1]) | |
({`VRAM_MSB+1{gfx_mode_16_bpp}} & vid_ram_pixel_addr_nxt[`VRAM_MSB+0:0]) ; |
|
// Detect when a new word needs to be fetched from the memory |
// (i.e. detect when the RAM address is updated) |
reg vid_ram_addr_update; |
wire vid_ram_addr_update_nxt = (vid_ram_addr_o != vid_ram_addr_nxt); |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) vid_ram_addr_update <= 1'h0; |
else if (~refresh_active_i) vid_ram_addr_update <= 1'h1; |
else if (vid_ram_pixel_done) vid_ram_addr_update <= vid_ram_addr_update_nxt; |
|
|
// Disable RAM access if there is no need to fetch a new word |
assign vid_ram_cen_o = vid_ram_addr_update ? ~fifo_data_request : 1'b1; |
|
// If the next FIFO data doesn't come from the RAM, then it is ready as |
// soon as it is requested |
assign fifo_data_ready = vid_ram_addr_update ? vid_ram_dout_rdy_nxt_i : fifo_data_request; |
|
|
//============================================================================ |
// 2) FRAME DATA-PRE-PROCESSING (PRIOR BEING PUSHED INTO FIFO) |
//============================================================================ |
|
//-------------------------------- |
// Data buffer |
//-------------------------------- |
// For the LUT modes, it is not necessary to access the RAM for |
// every pixel. In that case, the FIFO is filled with the values |
// coming from the buffer. |
// (i.e. we only take data directly from the RAM when it is just read) |
reg [15:0] vid_ram_dout_buf; |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) vid_ram_dout_buf <= 16'h0000; |
else if (vid_ram_dout_ready) vid_ram_dout_buf <= vid_ram_dout_i; |
|
wire [15:0] vid_ram_dout_mux = vid_ram_dout_ready ? vid_ram_dout_i : vid_ram_dout_buf; |
|
//-------------------------------- |
// Data formating |
//-------------------------------- |
// Depending on the mode, the address LSBs are used to select which bits |
// of the current data word need to be put in the FIFO |
wire [3:0] vid_ram_data_sel_nxt = ({4{gfx_mode_1_bpp}} & {vid_ram_pixel_addr[3:0] }) | |
({4{gfx_mode_2_bpp}} & {vid_ram_pixel_addr[2:0], 1'b0 }) | |
({4{gfx_mode_4_bpp}} & {vid_ram_pixel_addr[1:0], 2'b00 }) | |
({4{gfx_mode_8_bpp}} & {vid_ram_pixel_addr[0], 3'b000 }) ; |
|
reg [3:0] vid_ram_data_sel; |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) vid_ram_data_sel <= 4'h0; |
else if (vid_ram_pixel_done) vid_ram_data_sel <= vid_ram_data_sel_nxt; |
|
|
wire [15:0] vid_ram_dout_shifted = (vid_ram_dout_mux >> vid_ram_data_sel); |
|
// Format data output for LUT processing |
// (8 bit LSBs are used to address the LUT memory, MSBs are ignored) |
assign vid_ram_dout_processed = ({16{gfx_mode_1_bpp }} & {8'h00, 7'b0000000, vid_ram_dout_shifted[0] }) | |
({16{gfx_mode_2_bpp }} & {8'h00, 6'b000000 , vid_ram_dout_shifted[1:0]}) | |
({16{gfx_mode_4_bpp }} & {8'h00, 4'b0000 , vid_ram_dout_shifted[3:0]}) | |
({16{gfx_mode_8_bpp }} & {8'h00, vid_ram_dout_shifted[7:0]}) | |
({16{gfx_mode_16_bpp}} & { vid_ram_dout_shifted[15:0] }) ; |
|
//-------------------------------- |
// Data Ready |
//-------------------------------- |
// Data is available on the bus one cycle after the rdy_nxt signals |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) vid_ram_data_mux_ready <= 1'b0; |
else vid_ram_data_mux_ready <= fifo_data_ready; |
|
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) vid_ram_dout_ready <= 1'b0; |
else vid_ram_dout_ready <= vid_ram_dout_rdy_nxt_i; |
|
|
//============================================================================ |
// 3) FIFO COUNTER |
//============================================================================ |
|
// Declaration |
// Control signals |
wire fifo_push = vid_ram_data_mux_ready & (fifo_counter != FIFO_FULL); |
wire fifo_pop = read_from_fifo & (fifo_counter != FIFO_EMPTY); |
|
// Fifo counter |
assign fifo_counter_nxt = ~refresh_active_i ? FIFO_EMPTY : // Initialize |
(fifo_push & fifo_pop) ? fifo_counter : // Keep value (pop & push at the same time) |
fifo_push ? fifo_counter + 2'h1 : // Push |
fifo_pop ? fifo_counter - 2'h1 : // Pop |
fifo_counter; // Hold |
|
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) fifo_counter <= FIFO_EMPTY; |
else fifo_counter <= fifo_counter_nxt; |
|
|
//============================================================================ |
// 4) FIFO MEMORY & RD/WR POINTERS |
//============================================================================ |
|
// Write pointer |
reg [1:0] wr_ptr; |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) wr_ptr <= 2'h0; |
else if (~refresh_active_i) wr_ptr <= 2'h0; |
else if (fifo_push) |
begin |
if (wr_ptr==(FIFO_FULL-1)) wr_ptr <= 2'h0; |
else wr_ptr <= wr_ptr + 2'h1; |
end |
|
// Memory |
reg [15:0] fifo_mem [0:2]; |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) |
begin |
fifo_mem[0] <= 16'h0000; |
fifo_mem[1] <= 16'h0000; |
fifo_mem[2] <= 16'h0000; |
end |
else if (fifo_push) |
begin |
fifo_mem[wr_ptr] <= vid_ram_dout_processed; |
end |
|
// Read pointer |
reg [1:0] rd_ptr; |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) rd_ptr <= 2'h0; |
else if (~refresh_active_i) rd_ptr <= 2'h0; |
else if (fifo_pop) |
begin |
if (rd_ptr==(FIFO_FULL-1)) rd_ptr <= 2'h0; |
else rd_ptr <= rd_ptr + 2'h1; |
end |
|
|
//============================================================================ |
// 5) FRAME DATA FROM FIFO |
//============================================================================ |
|
// RAW Data is valid |
reg frame_data_init; |
wire frame_data_init_nxt = ~refresh_active_i ? 1'h0 : |
fifo_pop ? 1'b1 : frame_data_init; |
|
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) frame_data_init <= 1'h0; |
else frame_data_init <= frame_data_init_nxt; |
|
// RAW Data from the frame buffer |
reg [15:0] frame_data_o; |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) frame_data_o <= 16'h0000; |
else if (fifo_pop) frame_data_o <= fifo_mem[rd_ptr]; |
|
// Data is ready |
assign frame_data_ready_o = frame_data_init_nxt & (fifo_counter != FIFO_EMPTY); |
|
// Read from FIFO command |
assign read_from_fifo = ~refresh_active_i | |
~frame_data_init | |
((fifo_counter != FIFO_EMPTY) & frame_data_request_i); |
|
|
endmodule // ogfx_backend_frame_fifo |
|
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_undefines.v" |
`endif |
/trunk/core/rtl/verilog/ogfx_gpu_dma_addr.v
0,0 → 1,152
//---------------------------------------------------------------------------- |
// 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 |
/trunk/core/rtl/verilog/openGFX430_defines.v
0,0 → 1,213
//---------------------------------------------------------------------------- |
// Copyright (C) 2009 , Olivier Girard |
// |
// Redistribution and use in source and binary forms, with or without |
// modification, are permitted provided that the following conditions |
// are met: |
// * Redistributions of source code must retain the above copyright |
// notice, this list of conditions and the following disclaimer. |
// * Redistributions in binary form must reproduce the above copyright |
// notice, this list of conditions and the following disclaimer in the |
// documentation and/or other materials provided with the distribution. |
// * Neither the name of the authors nor the names of its contributors |
// may be used to endorse or promote products derived from this software |
// without specific prior written permission. |
// |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, |
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
// THE POSSIBILITY OF SUCH DAMAGE |
// |
//---------------------------------------------------------------------------- |
// |
// *File Name: openGFX430_defines.v |
// |
// *Module Description: |
// oMSP Graphic Controller Configuration file |
// |
// *Author(s): |
// - Olivier Girard, olgirard@gmail.com |
// |
//---------------------------------------------------------------------------- |
// $Rev: 103 $ |
// $LastChangedBy: olivier.girard $ |
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $ |
//---------------------------------------------------------------------------- |
//`define OGFX_NO_INCLUDE |
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_undefines.v" |
`endif |
|
//============================================================================ |
// GRAPHIC CONTROLLER USER CONFIGURATION |
//============================================================================ |
|
//----------------------------------------------------- |
// Video display maximum pixel height/width |
//----------------------------------------------------- |
//`define MAX_DISPLAY_PIXEL_LENGTH_4096 |
//`define MAX_DISPLAY_PIXEL_LENGTH_2048 |
//`define MAX_DISPLAY_PIXEL_LENGTH_1024 |
`define MAX_DISPLAY_PIXEL_LENGTH_512 |
//`define MAX_DISPLAY_PIXEL_LENGTH_256 |
//`define MAX_DISPLAY_PIXEL_LENGTH_128 |
//`define MAX_DISPLAY_PIXEL_LENGTH_64 |
//`define MAX_DISPLAY_PIXEL_LENGTH_32 |
|
//----------------------------------------------------- |
// Video memory address width |
//----------------------------------------------------- |
`define VRAM_AWIDTH 17 |
|
//----------------------------------------------------- |
// Define if the Video memory is bigger than 4k Words |
// (should be defined if VRAM_AWIDTH is bigger than 12) |
//----------------------------------------------------- |
`define VRAM_BIGGER_4_KW |
|
//----------------------------------------------------- |
// Include/Exclude Frame buffer pointers from the |
// register map |
// (Frame pointer 0 is always included) |
//----------------------------------------------------- |
`define WITH_FRAME1_POINTER |
//`define WITH_FRAME2_POINTER |
//`define WITH_FRAME3_POINTER |
|
//----------------------------------------------------- |
// LUT Configuration |
//----------------------------------------------------- |
`define WITH_PROGRAMMABLE_LUT |
`define WITH_EXTRA_LUT_BANK |
|
|
|
//==========================================================================// |
//==========================================================================// |
//==========================================================================// |
//==========================================================================// |
//===== SYSTEM CONSTANTS --- !!!!!!!! DO NOT EDIT !!!!!!!! =====// |
//==========================================================================// |
//==========================================================================// |
//==========================================================================// |
//==========================================================================// |
|
`ifdef MAX_DISPLAY_PIXEL_LENGTH_4096 |
`define LPIX_MSB 11 |
`define LPIX_SIZE 4096 |
`define WITH_DISPLAY_SIZE_HI |
`endif |
`ifdef MAX_DISPLAY_PIXEL_LENGTH_2048 |
`define LPIX_MSB 10 |
`define LPIX_SIZE 2048 |
`define WITH_DISPLAY_SIZE_HI |
`endif |
`ifdef MAX_DISPLAY_PIXEL_LENGTH_1024 |
`define LPIX_MSB 9 |
`define LPIX_SIZE 1024 |
`define WITH_DISPLAY_SIZE_HI |
`endif |
`ifdef MAX_DISPLAY_PIXEL_LENGTH_512 |
`define LPIX_MSB 8 |
`define LPIX_SIZE 512 |
`define WITH_DISPLAY_SIZE_HI |
`endif |
`ifdef MAX_DISPLAY_PIXEL_LENGTH_256 |
`define LPIX_MSB 7 |
`define LPIX_SIZE 256 |
`endif |
`ifdef MAX_DISPLAY_PIXEL_LENGTH_128 |
`define LPIX_MSB 6 |
`define LPIX_SIZE 128 |
`endif |
`ifdef MAX_DISPLAY_PIXEL_LENGTH_64 |
`define LPIX_MSB 5 |
`define LPIX_SIZE 64 |
`endif |
`ifdef MAX_DISPLAY_PIXEL_LENGTH_32 |
`define LPIX_MSB 4 |
`define LPIX_SIZE 32 |
`endif |
`define SPIX_MSB (((`LPIX_MSB+1)*2)-1) |
`ifdef WITH_DISPLAY_SIZE_HI |
`define SPIX_HI_MSB (`SPIX_MSB-16) |
`define SPIX_LO_MSB 15 |
`else |
`define SPIX_LO_MSB `SPIX_MSB |
`endif |
|
`define VRAM_MSB (`VRAM_AWIDTH-1) |
|
`define APIX_WIDTH (`VRAM_AWIDTH+4) |
`define APIX_MSB (`APIX_WIDTH-1) |
`ifdef VRAM_BIGGER_4_KW |
`define APIX_HI_MSB (`APIX_MSB-16) |
`define APIX_LO_MSB 15 |
`else |
`define APIX_LO_MSB `APIX_MSB |
`endif |
|
`ifdef WITH_EXTRA_LUT_BANK |
`define LRAM_AWIDTH 9 |
`else |
`define LRAM_AWIDTH 8 |
`endif |
`define LRAM_MSB (`LRAM_AWIDTH-1) |
|
|
// Opcodes for GPU commands |
`define OP_EXEC_FILL 2'b00 |
`define OP_EXEC_COPY 2'b01 |
`define OP_EXEC_COPY_TRANS 2'b10 |
`define OP_REC_WIDTH 4'b1100 |
`define OP_REC_HEIGHT 4'b1101 |
`define OP_SRC_PX_ADDR {4'b1111, 2'b10, 10'b0000000000} |
`define OP_DST_PX_ADDR {4'b1111, 2'b10, 10'b0000000001} |
`define OP_OF0_ADDR {4'b1111, 2'b10, 10'b0000010000} |
`define OP_OF1_ADDR {4'b1111, 2'b10, 10'b0000010001} |
`define OP_OF2_ADDR {4'b1111, 2'b10, 10'b0000010010} |
`define OP_OF3_ADDR {4'b1111, 2'b10, 10'b0000010011} |
`define OP_SET_FILL {4'b1111, 2'b01, 10'b0000100000} |
`define OP_SET_TRANSPARENT {4'b1111, 2'b01, 10'b0000100001} |
|
// Bit possitions of the GPU Command |
`define SRC_OFFSET 13:12 |
`define SRC_X_SWAP 11 |
`define SRC_Y_SWAP 10 |
`define SRC_CL_SWAP 9 |
`define PX_OP 8:5 |
`define DST_OFFSET 4:3 |
`define DST_X_SWAP 2 |
`define DST_Y_SWAP 1 |
`define DST_CL_SWAP 0 |
|
|
//---------------------------------- |
// Configuration checkers |
//---------------------------------- |
`ifdef WITH_FRAME2_POINTER |
`ifdef WITH_FRAME1_POINTER |
`else |
GFX CONTROLLER CONFIGURATION ERROR: ENABLED FRAME2 POINTER WITHOUT FRAME1 POINTER |
`endif |
`endif |
`ifdef WITH_FRAME3_POINTER |
`ifdef WITH_FRAME2_POINTER |
`else |
GFX CONTROLLER CONFIGURATION ERROR: ENABLED FRAME2 POINTER WITHOUT FRAME1 POINTER |
`endif |
`endif |
`ifdef WITH_PROGRAMMABLE_LUT |
`else |
`ifdef WITH_EXTRA_LUT_BANK |
GFX CONTROLLER CONFIGURATION ERROR: NOT ALLOWED TO ENABLE EXTRA LUT BANK IF PROGRAMMABLE LUT SUPPORT IS DISABLED |
`endif |
`endif |
/trunk/core/rtl/verilog/openGFX430_undefines.v
0,0 → 1,62
//---------------------------------------------------------------------------- |
// Copyright (C) 2009 , Olivier Girard |
// |
// Redistribution and use in source and binary forms, with or without |
// modification, are permitted provided that the following conditions |
// are met: |
// * Redistributions of source code must retain the above copyright |
// notice, this list of conditions and the following disclaimer. |
// * Redistributions in binary form must reproduce the above copyright |
// notice, this list of conditions and the following disclaimer in the |
// documentation and/or other materials provided with the distribution. |
// * Neither the name of the authors nor the names of its contributors |
// may be used to endorse or promote products derived from this software |
// without specific prior written permission. |
// |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, |
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
// THE POSSIBILITY OF SUCH DAMAGE |
// |
//---------------------------------------------------------------------------- |
// |
// *File Name: openGFX430_undefines.v |
// |
// *Module Description: |
// oMSP Graphic Controller Verilog `undef file |
// |
// *Author(s): |
// - Olivier Girard, olgirard@gmail.com |
// |
//---------------------------------------------------------------------------- |
// $Rev: 23 $ |
// $LastChangedBy: olivier.girard $ |
// $LastChangedDate: 2009-08-30 18:39:26 +0200 (Sun, 30 Aug 2009) $ |
//---------------------------------------------------------------------------- |
|
//---------------------------------------------------------------------------- |
// GRAPHIC CONTROLLER USER CONFIGURATION |
//---------------------------------------------------------------------------- |
|
|
|
//==========================================================================// |
//==========================================================================// |
//==========================================================================// |
//==========================================================================// |
//===== SYSTEM CONSTANTS --- !!!!!!!! DO NOT EDIT !!!!!!!! =====// |
//==========================================================================// |
//==========================================================================// |
//==========================================================================// |
//==========================================================================// |
|
//`ifdef TASSELx |
//`undef TASSELx |
//`endif |
/trunk/core/rtl/verilog/openGFX430.v
0,0 → 1,482
//---------------------------------------------------------------------------- |
// Copyright (C) 2016 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: openGFX430.v |
// |
// *Module Description: |
// This is a basic video controller for the openMSP430. |
// |
// It is currently supporting the LT24 LCD Board but |
// can be extended to anything. |
// |
// *Author(s): |
// - Olivier Girard, olgirard@gmail.com |
// |
//---------------------------------------------------------------------------- |
// $Rev$ |
// $LastChangedBy$ |
// $LastChangedDate$ |
//---------------------------------------------------------------------------- |
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_defines.v" |
`endif |
|
module openGFX430 ( |
|
// OUTPUTs |
irq_gfx_o, // Graphic Controller interrupt |
|
lt24_cs_n_o, // LT24 Chip select (Active low) |
lt24_rd_n_o, // LT24 Read strobe (Active low) |
lt24_wr_n_o, // LT24 Write strobe (Active low) |
lt24_rs_o, // LT24 Command/Param selection (Cmd=0/Param=1) |
lt24_d_o, // LT24 Data output |
lt24_d_en_o, // LT24 Data output enable |
lt24_reset_n_o, // LT24 Reset (Active Low) |
lt24_on_o, // LT24 on/off |
|
per_dout_o, // Peripheral data output |
|
`ifdef WITH_PROGRAMMABLE_LUT |
lut_ram_addr_o, // LUT-RAM address |
lut_ram_wen_o, // LUT-RAM write enable (active low) |
lut_ram_cen_o, // LUT-RAM enable (active low) |
lut_ram_din_o, // LUT-RAM data input |
`endif |
|
vid_ram_addr_o, // Video-RAM address |
vid_ram_wen_o, // Video-RAM write enable (active low) |
vid_ram_cen_o, // Video-RAM enable (active low) |
vid_ram_din_o, // Video-RAM data input |
|
// INPUTs |
dbg_freeze_i, // Freeze address auto-incr on read |
mclk, // Main system clock |
per_addr_i, // Peripheral address |
per_din_i, // Peripheral data input |
per_en_i, // Peripheral enable (high active) |
per_we_i, // Peripheral write enable (high active) |
puc_rst, // Main system reset |
|
lt24_d_i, // LT24 Data input |
|
`ifdef WITH_PROGRAMMABLE_LUT |
lut_ram_dout_i, // LUT-RAM data output |
`endif |
vid_ram_dout_i // Video-RAM data output |
); |
|
// OUTPUTs |
//========= |
output irq_gfx_o; // Graphic Controller interrupt |
|
output lt24_cs_n_o; // LT24 Chip select (Active low) |
output lt24_rd_n_o; // LT24 Read strobe (Active low) |
output lt24_wr_n_o; // LT24 Write strobe (Active low) |
output lt24_rs_o; // LT24 Command/Param selection (Cmd=0/Param=1) |
output [15:0] lt24_d_o; // LT24 Data output |
output lt24_d_en_o; // LT24 Data output enable |
output lt24_reset_n_o; // LT24 Reset (Active Low) |
output lt24_on_o; // LT24 on/off |
|
output [15:0] per_dout_o; // Peripheral data output |
|
`ifdef WITH_PROGRAMMABLE_LUT |
output [`LRAM_MSB:0] lut_ram_addr_o; // LUT-RAM address |
output lut_ram_wen_o; // LUT-RAM write enable (active low) |
output lut_ram_cen_o; // LUT-RAM enable (active low) |
output [15:0] lut_ram_din_o; // LUT-RAM data input |
`endif |
|
output [`VRAM_MSB:0] vid_ram_addr_o; // Video-RAM address |
output vid_ram_wen_o; // Video-RAM write enable (active low) |
output vid_ram_cen_o; // Video-RAM enable (active low) |
output [15:0] vid_ram_din_o; // Video-RAM data input |
|
// INPUTs |
//========= |
input dbg_freeze_i; // Freeze address auto-incr on read |
input mclk; // Main system clock |
input [13:0] per_addr_i; // Peripheral address |
input [15:0] per_din_i; // Peripheral data input |
input per_en_i; // Peripheral enable (high active) |
input [1:0] per_we_i; // Peripheral write enable (high active) |
input puc_rst; // Main system reset |
|
input [15:0] lt24_d_i; // LT24 Data input |
|
`ifdef WITH_PROGRAMMABLE_LUT |
input [15:0] lut_ram_dout_i; // LUT-RAM data output |
`endif |
input [15:0] vid_ram_dout_i; // Video-RAM data output |
|
|
//============================================================================= |
// 1) WIRE & PARAMETER DECLARATION |
//============================================================================= |
|
wire [2:0] lt24_cfg_clk; |
wire [11:0] lt24_cfg_refr; |
wire lt24_cfg_refr_sync_en; |
wire [9:0] lt24_cfg_refr_sync_val; |
wire lt24_cmd_refr; |
wire [7:0] lt24_cmd_val; |
wire lt24_cmd_has_param; |
wire [15:0] lt24_cmd_param; |
wire lt24_cmd_param_rdy; |
wire [15:0] lt24_cmd_dfill; |
wire lt24_cmd_dfill_wr; |
|
wire [`LPIX_MSB:0] display_width; |
wire [`LPIX_MSB:0] display_height; |
wire [`SPIX_MSB:0] display_size; |
wire display_y_swap; |
wire display_x_swap; |
wire display_cl_swap; |
wire [2:0] gfx_mode; |
|
wire [4:0] lt24_status; |
wire lt24_done_evt; |
wire lt24_start_evt; |
|
`ifdef WITH_PROGRAMMABLE_LUT |
wire [`LRAM_MSB:0] lut_ram_sw_addr; |
wire [15:0] lut_ram_sw_din; |
wire lut_ram_sw_wen; |
wire lut_ram_sw_cen; |
wire [15:0] lut_ram_sw_dout; |
wire [`LRAM_MSB:0] lut_ram_refr_addr; |
wire lut_ram_refr_cen; |
wire [15:0] lut_ram_refr_dout; |
wire lut_ram_refr_dout_rdy_nxt; |
`endif |
wire [`VRAM_MSB:0] vid_ram_sw_addr; |
wire [15:0] vid_ram_sw_din; |
wire vid_ram_sw_wen; |
wire vid_ram_sw_cen; |
wire [15:0] vid_ram_sw_dout; |
wire [`VRAM_MSB:0] vid_ram_gpu_addr; |
wire [15:0] vid_ram_gpu_din; |
wire vid_ram_gpu_wen; |
wire vid_ram_gpu_cen; |
wire [15:0] vid_ram_gpu_dout; |
wire vid_ram_gpu_dout_rdy_nxt; |
wire [`VRAM_MSB:0] vid_ram_refr_addr; |
wire vid_ram_refr_cen; |
wire [15:0] vid_ram_refr_dout; |
wire vid_ram_refr_dout_rdy_nxt; |
|
wire refresh_active; |
wire [15:0] refresh_data; |
wire refresh_data_ready; |
wire refresh_data_request; |
wire [`APIX_MSB:0] refresh_frame_addr; |
wire [1:0] refresh_lut_select; |
|
wire gpu_cmd_done_evt; |
wire gpu_cmd_error_evt; |
wire gpu_get_data; |
wire [15:0] gpu_data; |
wire gpu_data_avail; |
wire gpu_enable; |
|
|
//============================================================================ |
// 2) REGISTERS |
//============================================================================ |
|
ogfx_reg ogfx_reg_inst ( |
|
// OUTPUTs |
.irq_gfx_o ( irq_gfx_o ), // Graphic Controller interrupt |
|
.gpu_data_o ( gpu_data ), // GPU data |
.gpu_data_avail_o ( gpu_data_avail ), // GPU data available |
.gpu_enable_o ( gpu_enable ), // GPU enable |
|
.lt24_reset_n_o ( lt24_reset_n_o ), // LT24 Reset (Active Low) |
.lt24_on_o ( lt24_on_o ), // LT24 on/off |
.lt24_cfg_clk_o ( lt24_cfg_clk ), // LT24 Interface clock configuration |
.lt24_cfg_refr_o ( lt24_cfg_refr ), // LT24 Interface refresh configuration |
.lt24_cfg_refr_sync_en_o ( lt24_cfg_refr_sync_en ), // LT24 Interface refresh sync enable configuration |
.lt24_cfg_refr_sync_val_o ( lt24_cfg_refr_sync_val ), // LT24 Interface refresh sync value configuration |
.lt24_cmd_refr_o ( lt24_cmd_refr ), // LT24 Interface refresh command |
.lt24_cmd_val_o ( lt24_cmd_val ), // LT24 Generic command value |
.lt24_cmd_has_param_o ( lt24_cmd_has_param ), // LT24 Generic command has parameters |
.lt24_cmd_param_o ( lt24_cmd_param ), // LT24 Generic command parameter value |
.lt24_cmd_param_rdy_o ( lt24_cmd_param_rdy ), // LT24 Generic command trigger |
.lt24_cmd_dfill_o ( lt24_cmd_dfill ), // LT24 Data fill value |
.lt24_cmd_dfill_wr_o ( lt24_cmd_dfill_wr ), // LT24 Data fill trigger |
|
.display_width_o ( display_width ), // Display width |
.display_height_o ( display_height ), // Display height |
.display_size_o ( display_size ), // Display size (number of pixels) |
.display_y_swap_o ( display_y_swap ), // Display configuration: swap Y axis (horizontal symmetry) |
.display_x_swap_o ( display_x_swap ), // Display configuration: swap X axis (vertical symmetry) |
.display_cl_swap_o ( display_cl_swap ), // Display configuration: swap column/lines |
|
.gfx_mode_o ( gfx_mode ), // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp) |
|
.per_dout_o ( per_dout_o ), // Peripheral data output |
|
.refresh_frame_addr_o ( refresh_frame_addr ), // Refresh frame base address |
.refresh_lut_select_o ( refresh_lut_select ), // Refresh LUT bank selection |
|
`ifdef WITH_PROGRAMMABLE_LUT |
.lut_ram_addr_o ( lut_ram_sw_addr ), // LUT-RAM address |
.lut_ram_din_o ( lut_ram_sw_din ), // LUT-RAM data |
.lut_ram_wen_o ( lut_ram_sw_wen ), // LUT-RAM write strobe (active low) |
.lut_ram_cen_o ( lut_ram_sw_cen ), // LUT-RAM chip enable (active low) |
`endif |
|
.vid_ram_addr_o ( vid_ram_sw_addr ), // Video-RAM address |
.vid_ram_din_o ( vid_ram_sw_din ), // Video-RAM data |
.vid_ram_wen_o ( vid_ram_sw_wen ), // Video-RAM write strobe (active low) |
.vid_ram_cen_o ( vid_ram_sw_cen ), // Video-RAM chip enable (active low) |
|
// INPUTs |
.dbg_freeze_i ( dbg_freeze_i ), // Freeze address auto-incr on read |
.gpu_cmd_done_evt_i ( gpu_cmd_done_evt ), // GPU command done event |
.gpu_cmd_error_evt_i ( gpu_cmd_error_evt ), // GPU command error event |
.gpu_get_data_i ( gpu_get_data ), // GPU get next data |
.lt24_status_i ( lt24_status ), // LT24 FSM Status |
.lt24_start_evt_i ( lt24_start_evt ), // LT24 FSM start event |
.lt24_done_evt_i ( lt24_done_evt ), // LT24 FSM done event |
.mclk ( mclk ), // Main system clock |
.per_addr_i ( per_addr_i ), // Peripheral address |
.per_din_i ( per_din_i ), // Peripheral data input |
.per_en_i ( per_en_i ), // Peripheral enable (high active) |
.per_we_i ( per_we_i ), // Peripheral write enable (high active) |
.puc_rst ( puc_rst ), // Main system reset |
|
`ifdef WITH_PROGRAMMABLE_LUT |
.lut_ram_dout_i ( lut_ram_sw_dout ), // LUT-RAM data input |
`endif |
.vid_ram_dout_i ( vid_ram_sw_dout ) // Video-RAM data input |
); |
|
|
//============================================================================ |
// 3) GPU |
//============================================================================ |
|
ogfx_gpu ogfx_gpu_inst ( |
|
// OUTPUTs |
.gpu_cmd_done_evt_o ( gpu_cmd_done_evt ), // GPU command done event |
.gpu_cmd_error_evt_o ( gpu_cmd_error_evt ), // GPU command error event |
.gpu_get_data_o ( gpu_get_data ), // GPU get next data |
|
.vid_ram_addr_o ( vid_ram_gpu_addr ), // Video-RAM address |
.vid_ram_din_o ( vid_ram_gpu_din ), // Video-RAM data |
.vid_ram_wen_o ( vid_ram_gpu_wen ), // Video-RAM write strobe (active low) |
.vid_ram_cen_o ( vid_ram_gpu_cen ), // Video-RAM chip enable (active low) |
|
// INPUTs |
.mclk ( mclk ), // Main system clock |
.puc_rst ( puc_rst ), // Main system reset |
|
.display_width_i ( display_width ), // Display width |
|
.gfx_mode_i ( gfx_mode ), // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp) |
|
.gpu_data_i ( gpu_data ), // GPU data |
.gpu_data_avail_i ( gpu_data_avail ), // GPU data available |
.gpu_enable_i ( gpu_enable ), // GPU enable |
|
.vid_ram_dout_i ( vid_ram_gpu_dout ), // Video-RAM data input |
.vid_ram_dout_rdy_nxt_i ( vid_ram_gpu_dout_rdy_nxt ) // Video-RAM data output ready during next cycle |
); |
|
|
//============================================================================ |
// 4) LT24 INTERFACE |
//============================================================================ |
|
ogfx_if_lt24 ogfx_if_lt24_inst ( |
|
// OUTPUTs |
.event_fsm_done_o ( lt24_done_evt ), // LT24 FSM done event |
.event_fsm_start_o ( lt24_start_evt ), // LT24 FSM start event |
|
.lt24_cs_n_o ( lt24_cs_n_o ), // LT24 Chip select (Active low) |
.lt24_d_o ( lt24_d_o ), // LT24 Data output |
.lt24_d_en_o ( lt24_d_en_o ), // LT24 Data output enable |
.lt24_rd_n_o ( lt24_rd_n_o ), // LT24 Read strobe (Active low) |
.lt24_rs_o ( lt24_rs_o ), // LT24 Command/Param selection (Cmd=0/Param=1) |
.lt24_wr_n_o ( lt24_wr_n_o ), // LT24 Write strobe (Active low) |
|
.refresh_active_o ( refresh_active ), // Display refresh on going |
.refresh_data_request_o ( refresh_data_request ), // Display refresh new data request |
|
.status_o ( lt24_status ), // LT24 FSM Status |
|
// INPUTs |
.mclk ( mclk ), // Main system clock |
.puc_rst ( puc_rst ), // Main system reset |
|
.cfg_lt24_clk_div_i ( lt24_cfg_clk ), // Clock Divider configuration for LT24 interface |
.cfg_lt24_display_size_i ( display_size ), // Display size (number of pixels) |
.cfg_lt24_refresh_i ( lt24_cfg_refr ), // Refresh rate configuration for LT24 interface |
.cfg_lt24_refresh_sync_en_i ( lt24_cfg_refr_sync_en ), // Refresh sync enable configuration for LT24 interface |
.cfg_lt24_refresh_sync_val_i ( lt24_cfg_refr_sync_val ), // Refresh sync value configuration for LT24 interface |
|
.cmd_dfill_i ( lt24_cmd_dfill ), // Display data fill |
.cmd_dfill_trig_i ( lt24_cmd_dfill_wr ), // Trigger a full display data fill |
|
.cmd_generic_cmd_val_i ( lt24_cmd_val ), // Generic command value |
.cmd_generic_has_param_i ( lt24_cmd_has_param ), // Generic command to be sent has parameter(s) |
.cmd_generic_param_val_i ( lt24_cmd_param ), // Generic command parameter value |
.cmd_generic_trig_i ( lt24_cmd_param_rdy ), // Trigger generic command transmit (or new parameter available) |
|
.cmd_refresh_i ( lt24_cmd_refr ), // Display refresh command |
|
.lt24_d_i ( lt24_d_i ), // LT24 Data input |
|
.refresh_data_i ( refresh_data ), // Display refresh data |
.refresh_data_ready_i ( refresh_data_ready ) // Display refresh new data is ready |
); |
|
//============================================================================ |
// 5) VIDEO BACKEND |
//============================================================================ |
|
// Video Backend |
ogfx_backend ogfx_backend_inst ( |
|
// OUTPUTs |
.refresh_data_o ( refresh_data ), // Display refresh data |
.refresh_data_ready_o ( refresh_data_ready ), // Display refresh new data is ready |
|
.vid_ram_addr_o ( vid_ram_refr_addr ), // Video-RAM address |
.vid_ram_cen_o ( vid_ram_refr_cen ), // Video-RAM enable (active low) |
|
`ifdef WITH_PROGRAMMABLE_LUT |
.lut_ram_addr_o ( lut_ram_refr_addr ), // LUT-RAM address |
.lut_ram_cen_o ( lut_ram_refr_cen ), // LUT-RAM enable (active low) |
`endif |
|
// INPUTs |
.mclk ( mclk ), // Main system clock |
.puc_rst ( puc_rst ), // Main system reset |
|
.display_width_i ( display_width ), // Display width |
.display_height_i ( display_height ), // Display height |
.display_size_i ( display_size ), // Display size (number of pixels) |
.display_y_swap_i ( display_y_swap ), // Display configuration: swap Y axis (horizontal symmetry) |
.display_x_swap_i ( display_x_swap ), // Display configuration: swap X axis (vertical symmetry) |
.display_cl_swap_i ( display_cl_swap ), // Display configuration: swap column/lines |
|
.gfx_mode_i ( gfx_mode ), // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp) |
|
`ifdef WITH_PROGRAMMABLE_LUT |
.lut_ram_dout_i ( lut_ram_refr_dout ), // LUT-RAM data output |
.lut_ram_dout_rdy_nxt_i ( lut_ram_refr_dout_rdy_nxt ), // LUT-RAM data output ready during next cycle |
`endif |
|
.vid_ram_dout_i ( vid_ram_refr_dout ), // Video-RAM data output |
.vid_ram_dout_rdy_nxt_i ( vid_ram_refr_dout_rdy_nxt ), // Video-RAM data output ready during next cycle |
|
.refresh_active_i ( refresh_active ), // Display refresh on going |
.refresh_data_request_i ( refresh_data_request ), // Display refresh new data request |
.refresh_frame_base_addr_i ( refresh_frame_addr ), // Refresh frame base address |
.refresh_lut_select_i ( refresh_lut_select ) // Refresh LUT bank selection |
); |
|
//============================================================================ |
// 6) ARBITER FOR VIDEO AND LUT MEMORIES |
//============================================================================ |
|
ogfx_ram_arbiter ogfx_ram_arbiter_inst ( |
|
.mclk ( mclk ), // Main system clock |
.puc_rst ( puc_rst ), // Main system reset |
|
//------------------------------------------------------------ |
|
// SW interface, fixed highest priority |
.lut_ram_sw_addr_i ( lut_ram_sw_addr ), // LUT-RAM Software address |
.lut_ram_sw_din_i ( lut_ram_sw_din ), // LUT-RAM Software data |
.lut_ram_sw_wen_i ( lut_ram_sw_wen ), // LUT-RAM Software write strobe (active low) |
.lut_ram_sw_cen_i ( lut_ram_sw_cen ), // LUT-RAM Software chip enable (active low) |
.lut_ram_sw_dout_o ( lut_ram_sw_dout ), // LUT-RAM Software data input |
|
// Refresh-backend, fixed lowest priority |
.lut_ram_refr_addr_i ( lut_ram_refr_addr ), // LUT-RAM Refresh address |
.lut_ram_refr_din_i ( 16'h0000 ), // LUT-RAM Refresh data |
.lut_ram_refr_wen_i ( 1'h1 ), // LUT-RAM Refresh write strobe (active low) |
.lut_ram_refr_cen_i ( lut_ram_refr_cen ), // LUT-RAM Refresh enable (active low) |
.lut_ram_refr_dout_o ( lut_ram_refr_dout ), // LUT-RAM Refresh data output |
.lut_ram_refr_dout_rdy_nxt_o ( lut_ram_refr_dout_rdy_nxt ), // LUT-RAM Refresh data output ready during next cycle |
|
// LUT Memory interface |
.lut_ram_addr_o ( lut_ram_addr_o ), // LUT-RAM address |
.lut_ram_din_o ( lut_ram_din_o ), // LUT-RAM data |
.lut_ram_wen_o ( lut_ram_wen_o ), // LUT-RAM write strobe (active low) |
.lut_ram_cen_o ( lut_ram_cen_o ), // LUT-RAM chip enable (active low) |
.lut_ram_dout_i ( lut_ram_dout_i ), // LUT-RAM data input |
|
//------------------------------------------------------------ |
|
// SW interface, fixed highest priority |
.vid_ram_sw_addr_i ( vid_ram_sw_addr ), // Video-RAM Software address |
.vid_ram_sw_din_i ( vid_ram_sw_din ), // Video-RAM Software data |
.vid_ram_sw_wen_i ( vid_ram_sw_wen ), // Video-RAM Software write strobe (active low) |
.vid_ram_sw_cen_i ( vid_ram_sw_cen ), // Video-RAM Software chip enable (active low) |
.vid_ram_sw_dout_o ( vid_ram_sw_dout ), // Video-RAM Software data input |
|
// GPU interface (round-robin with refresh-backend) |
.vid_ram_gpu_addr_i ( vid_ram_gpu_addr ), // Video-RAM GPU address |
.vid_ram_gpu_din_i ( vid_ram_gpu_din ), // Video-RAM GPU data |
.vid_ram_gpu_wen_i ( vid_ram_gpu_wen ), // Video-RAM GPU write strobe (active low) |
.vid_ram_gpu_cen_i ( vid_ram_gpu_cen ), // Video-RAM GPU chip enable (active low) |
.vid_ram_gpu_dout_o ( vid_ram_gpu_dout ), // Video-RAM GPU data input |
.vid_ram_gpu_dout_rdy_nxt_o ( vid_ram_gpu_dout_rdy_nxt ), // Video-RAM GPU data output ready during next cycle |
|
// Refresh-backend (round-robin with GPU interface) |
.vid_ram_refr_addr_i ( vid_ram_refr_addr ), // Video-RAM Refresh address |
.vid_ram_refr_din_i ( 16'h0000 ), // Video-RAM Refresh data |
.vid_ram_refr_wen_i ( 1'h1 ), // Video-RAM Refresh write strobe (active low) |
.vid_ram_refr_cen_i ( vid_ram_refr_cen ), // Video-RAM Refresh enable (active low) |
.vid_ram_refr_dout_o ( vid_ram_refr_dout ), // Video-RAM Refresh data output |
.vid_ram_refr_dout_rdy_nxt_o ( vid_ram_refr_dout_rdy_nxt ), // Video-RAM Refresh data output ready during next cycle |
|
// Video Memory interface |
.vid_ram_addr_o ( vid_ram_addr_o ), // Video-RAM address |
.vid_ram_din_o ( vid_ram_din_o ), // Video-RAM data |
.vid_ram_wen_o ( vid_ram_wen_o ), // Video-RAM write strobe (active low) |
.vid_ram_cen_o ( vid_ram_cen_o ), // Video-RAM chip enable (active low) |
.vid_ram_dout_i ( vid_ram_dout_i ) // Video-RAM data input |
|
//------------------------------------------------------------ |
); |
|
|
endmodule // openGFX430 |
|
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_undefines.v" |
`endif |
/trunk/core/rtl/verilog/ogfx_gpu_dma.v
0,0 → 1,558
//---------------------------------------------------------------------------- |
// 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.v |
// |
// *Module Description: |
// Graphic-Processing unit 2D-DMA. |
// |
// *Author(s): |
// - Olivier Girard, olgirard@gmail.com |
// |
//---------------------------------------------------------------------------- |
// $Rev$ |
// $LastChangedBy$ |
// $LastChangedDate$ |
//---------------------------------------------------------------------------- |
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_defines.v" |
`endif |
|
module ogfx_gpu_dma ( |
|
// OUTPUTs |
gpu_exec_done_o, // GPU execution done |
|
vid_ram_addr_o, // Video-RAM address |
vid_ram_din_o, // Video-RAM data |
vid_ram_wen_o, // Video-RAM write strobe (active low) |
vid_ram_cen_o, // Video-RAM chip enable (active low) |
|
// INPUTs |
mclk, // Main system clock |
puc_rst, // Main system reset |
|
cfg_dst_px_addr_i, // Destination pixel address configuration |
cfg_dst_cl_swp_i, // Destination Column/Line-Swap configuration |
cfg_dst_x_swp_i, // Destination X-Swap configuration |
cfg_dst_y_swp_i, // Destination Y-Swap configuration |
cfg_fill_color_i, // Fill color (for rectangle fill operation) |
cfg_pix_op_sel_i, // Pixel operation to be performed during the copy |
cfg_rec_width_i, // Rectangle width configuration |
cfg_rec_height_i, // Rectangle height configuration |
cfg_src_px_addr_i, // Source pixel address configuration |
cfg_src_cl_swp_i, // Source Column/Line-Swap configuration |
cfg_src_x_swp_i, // Source X-Swap configuration |
cfg_src_y_swp_i, // Source Y-Swap configuration |
cfg_transparent_color_i, // Transparent color (for rectangle transparent copy operation) |
|
display_width_i, // Display width |
|
gfx_mode_i, // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp) |
|
gpu_enable_i, // GPU enable |
|
exec_fill_i, // Rectangle fill on going |
exec_copy_i, // Rectangle copy on going |
exec_copy_trans_i, // Rectangle transparent copy on going |
trig_exec_i, // Trigger rectangle execution |
|
vid_ram_dout_i, // Video-RAM data input |
vid_ram_dout_rdy_nxt_i // Video-RAM data output ready during next cycle |
); |
|
// OUTPUTs |
//========= |
output gpu_exec_done_o; // GPU execution done |
|
output [`VRAM_MSB:0] vid_ram_addr_o; // Video-RAM address |
output [15:0] vid_ram_din_o; // Video-RAM data |
output vid_ram_wen_o; // Video-RAM write strobe (active low) |
output vid_ram_cen_o; // Video-RAM chip enable (active low) |
|
// INPUTs |
//========= |
input mclk; // Main system clock |
input puc_rst; // Main system reset |
|
input [`APIX_MSB:0] cfg_dst_px_addr_i; // Destination pixel address configuration |
input cfg_dst_cl_swp_i; // Destination Column/Line-Swap configuration |
input cfg_dst_x_swp_i; // Destination X-Swap configuration |
input cfg_dst_y_swp_i; // Destination Y-Swap configuration |
input [15:0] cfg_fill_color_i; // Fill color (for rectangle fill operation) |
input [3:0] cfg_pix_op_sel_i; // Pixel operation to be performed during the copy |
input [`LPIX_MSB:0] cfg_rec_width_i; // Rectangle width configuration |
input [`LPIX_MSB:0] cfg_rec_height_i; // Rectangle height configuration |
input [`APIX_MSB:0] cfg_src_px_addr_i; // Source pixel address configuration |
input cfg_src_cl_swp_i; // Source Column/Line-Swap configuration |
input cfg_src_x_swp_i; // Source X-Swap configuration |
input cfg_src_y_swp_i; // Source Y-Swap configuration |
input [15:0] cfg_transparent_color_i; // Transparent color (for rectangle transparent copy operation) |
|
input [`LPIX_MSB:0] display_width_i; // Display width |
|
input [2:0] gfx_mode_i; // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp) |
|
input gpu_enable_i; // GPU enable |
|
input exec_fill_i; // Rectangle fill on going |
input exec_copy_i; // Rectangle copy on going |
input exec_copy_trans_i; // Rectangle transparent copy on going |
input trig_exec_i; // Trigger rectangle execution |
|
input [15:0] vid_ram_dout_i; // Video-RAM data input |
input vid_ram_dout_rdy_nxt_i; // Video-RAM data output ready during next cycle |
|
|
//============================================================================= |
// 1) WIRE, REGISTERS AND PARAMETER DECLARATION |
//============================================================================= |
|
// Video modes decoding |
wire gfx_mode_1_bpp = (gfx_mode_i == 3'b000); |
wire gfx_mode_2_bpp = (gfx_mode_i == 3'b001); |
wire gfx_mode_4_bpp = (gfx_mode_i == 3'b010); |
wire gfx_mode_8_bpp = (gfx_mode_i == 3'b011); |
wire gfx_mode_16_bpp = ~(gfx_mode_8_bpp | gfx_mode_4_bpp | gfx_mode_2_bpp | gfx_mode_1_bpp); |
|
|
// Pixel operation decoding |
wire pix_op_00 = (cfg_pix_op_sel_i == 4'b0000); // S |
wire pix_op_01 = (cfg_pix_op_sel_i == 4'b0001); // not S |
wire pix_op_02 = (cfg_pix_op_sel_i == 4'b0010); // not D |
|
wire pix_op_03 = (cfg_pix_op_sel_i == 4'b0011); // S and D |
wire pix_op_04 = (cfg_pix_op_sel_i == 4'b0100); // S or D |
wire pix_op_05 = (cfg_pix_op_sel_i == 4'b0101); // S xor D |
|
wire pix_op_06 = (cfg_pix_op_sel_i == 4'b0110); // not (S and D) |
wire pix_op_07 = (cfg_pix_op_sel_i == 4'b0111); // not (S or D) |
wire pix_op_08 = (cfg_pix_op_sel_i == 4'b1000); // not (S xor D) |
|
wire pix_op_09 = (cfg_pix_op_sel_i == 4'b1001); // (not S) and D |
wire pix_op_10 = (cfg_pix_op_sel_i == 4'b1010); // S and (not D) |
wire pix_op_11 = (cfg_pix_op_sel_i == 4'b1011); // (not S) or D |
wire pix_op_12 = (cfg_pix_op_sel_i == 4'b1100); // S or (not D) |
|
wire pix_op_13 = (cfg_pix_op_sel_i == 4'b1101); // Fill 0 if S not transparent |
wire pix_op_14 = (cfg_pix_op_sel_i == 4'b1110); // Fill 1 if S not transparent |
wire pix_op_15 = (cfg_pix_op_sel_i == 4'b1111); // Fill 'fill_color' if S not transparent |
|
wire dma_done; |
wire pixel_is_transparent; |
|
// 16 bits one-hot decoder |
function [15:0] one_hot16; |
input [3:0] binary; |
begin |
one_hot16 = 16'h0000; |
one_hot16[binary] = 1'b1; |
end |
endfunction |
|
|
//============================================================================= |
// 2) DMA STATE MACHINE |
//============================================================================= |
|
// State definition |
parameter IDLE = 3'h0; |
parameter INIT = 3'h1; |
parameter SKIP = 3'h2; |
parameter SRC_READ = 3'h3; |
parameter DST_READ = 3'h4; |
parameter DST_WRITE = 3'h5; |
|
// State machine |
reg [2:0] dma_state; |
reg [2:0] dma_state_nxt; |
|
// State arcs |
wire needs_src_read = (exec_copy_i & ~pix_op_02) | exec_copy_trans_i; |
wire needs_dst_read = (exec_fill_i | exec_copy_trans_i | exec_copy_i) & (~(pix_op_00 | pix_op_01 | pix_op_13 | pix_op_14 | pix_op_15) | ~gfx_mode_16_bpp); |
wire needs_dst_write = (exec_fill_i | exec_copy_trans_i | exec_copy_i) & ~pixel_is_transparent; |
|
wire data_ready_nxt = (dma_state==SRC_READ) | |
(((dma_state==DST_READ) | |
(dma_state==DST_WRITE)) & ~pixel_is_transparent) ? vid_ram_dout_rdy_nxt_i : 1'b1; |
|
// State transition |
always @(dma_state or trig_exec_i or needs_src_read or needs_dst_read or data_ready_nxt or dma_done or needs_dst_write) |
case (dma_state) |
IDLE : dma_state_nxt = ~trig_exec_i ? IDLE : INIT ; |
|
INIT : dma_state_nxt = needs_src_read ? SRC_READ : |
needs_dst_read ? DST_READ : |
needs_dst_write ? DST_WRITE : SKIP ; |
|
SKIP : dma_state_nxt = dma_done ? IDLE : SKIP ; |
|
SRC_READ : dma_state_nxt = ~data_ready_nxt ? SRC_READ : |
needs_dst_read ? DST_READ : DST_WRITE ; |
|
DST_READ : dma_state_nxt = ~data_ready_nxt ? DST_READ : |
needs_dst_write ? DST_WRITE : |
dma_done ? IDLE : SRC_READ ; |
|
DST_WRITE : dma_state_nxt = ~data_ready_nxt ? DST_WRITE : |
dma_done ? IDLE : |
needs_src_read ? SRC_READ : |
needs_dst_read ? DST_READ : DST_WRITE ; |
// pragma coverage off |
default : dma_state_nxt = IDLE; |
// pragma coverage on |
endcase |
|
// State machine |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) dma_state <= IDLE; |
else if (~gpu_enable_i) dma_state <= IDLE; |
else dma_state <= dma_state_nxt; |
|
|
// Utility signals |
wire dma_init = (dma_state==INIT); |
wire dma_pixel_done = (dma_state==SKIP) | ((dma_state==DST_READ) & pixel_is_transparent) | |
((dma_state==DST_WRITE) & data_ready_nxt ) ; |
assign gpu_exec_done_o = (dma_state==IDLE) & ~trig_exec_i; |
|
|
//============================================================================= |
// 3) COUNT TRANSFERS |
//============================================================================= |
reg [`LPIX_MSB:0] height_cnt; |
wire height_cnt_done; |
reg [`LPIX_MSB:0] width_cnt; |
wire width_cnt_done; |
|
// Height Counter |
wire height_cnt_init = dma_init; |
wire height_cnt_dec = dma_pixel_done & width_cnt_done & ~height_cnt_done; |
|
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) height_cnt <= {{`LPIX_MSB{1'h0}},1'b1}; |
else if (height_cnt_init) height_cnt <= cfg_rec_height_i; |
else if (height_cnt_dec) height_cnt <= height_cnt-{{`LPIX_MSB{1'h0}},1'b1}; |
|
assign height_cnt_done = (height_cnt=={{`LPIX_MSB{1'h0}}, 1'b1}); |
|
// Width Counter |
wire width_cnt_init = dma_init | height_cnt_dec; |
wire width_cnt_dec = dma_pixel_done & ~width_cnt_done; |
|
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) width_cnt <= {{`LPIX_MSB{1'h0}},1'b1}; |
else if (width_cnt_init) width_cnt <= cfg_rec_width_i; |
else if (width_cnt_dec) width_cnt <= width_cnt-{{`LPIX_MSB{1'h0}},1'b1}; |
|
assign width_cnt_done = (width_cnt=={{`LPIX_MSB{1'h0}}, 1'b1}); |
|
// DMA Transfer is done when both counters are done |
assign dma_done = height_cnt_done & width_cnt_done; |
|
|
//============================================================================= |
// 4) SOURCE ADDRESS GENERATION |
//============================================================================= |
|
reg [`APIX_MSB:0] vram_src_addr; |
wire [`APIX_MSB:0] vram_src_addr_calc; |
|
wire vram_src_addr_inc = dma_pixel_done & needs_src_read; |
wire [`APIX_MSB:0] vram_src_addr_nxt = trig_exec_i ? cfg_src_px_addr_i : vram_src_addr_calc; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) vram_src_addr <= {`APIX_MSB+1{1'b0}}; |
else if (trig_exec_i | vram_src_addr_inc) vram_src_addr <= vram_src_addr_nxt; |
|
|
// Compute the next address |
ogfx_gpu_dma_addr ogfx_gpu_dma_src_addr_inst ( |
|
// OUTPUTs |
.vid_ram_addr_nxt_o ( vram_src_addr_calc ), // Next Video-RAM address |
|
// INPUTs |
.mclk ( mclk ), // Main system clock |
.puc_rst ( puc_rst ), // Main system reset |
.display_width_i ( display_width_i ), // Display width |
.gfx_mode_1_bpp_i ( gfx_mode_1_bpp ), // Graphic mode 1 bpp resolution |
.gfx_mode_2_bpp_i ( gfx_mode_2_bpp ), // Graphic mode 2 bpp resolution |
.gfx_mode_4_bpp_i ( gfx_mode_4_bpp ), // Graphic mode 4 bpp resolution |
.gfx_mode_8_bpp_i ( gfx_mode_8_bpp ), // Graphic mode 8 bpp resolution |
.gfx_mode_16_bpp_i ( gfx_mode_16_bpp ), // Graphic mode 16 bpp resolution |
.vid_ram_addr_i ( vram_src_addr ), // Video-RAM address |
.vid_ram_addr_init_i ( dma_init ), // Video-RAM address initialization |
.vid_ram_addr_step_i ( vram_src_addr_inc ), // Video-RAM address step |
.vid_ram_width_i ( cfg_rec_width_i ), // Video-RAM width |
.vid_ram_win_x_swap_i ( cfg_src_x_swp_i ), // Video-RAM X-Swap configuration |
.vid_ram_win_y_swap_i ( cfg_src_y_swp_i ), // Video-RAM Y-Swap configuration |
.vid_ram_win_cl_swap_i ( cfg_src_cl_swp_i ) // Video-RAM CL-Swap configuration |
); |
|
//============================================================================= |
// 5) SOURCE DATA MASK |
//============================================================================= |
|
reg [15:0] vram_src_mask; |
wire [15:0] vram_src_mask_shift = one_hot16(vram_src_addr_nxt[3:0]); |
wire [15:0] vram_src_mask_vram_nxt = ({16{gfx_mode_1_bpp }} & vram_src_mask_shift ) | |
({16{gfx_mode_2_bpp }} & {{2{vram_src_mask_shift[14]}}, |
{2{vram_src_mask_shift[12]}}, |
{2{vram_src_mask_shift[10]}}, |
{2{vram_src_mask_shift[8] }}, |
{2{vram_src_mask_shift[6] }}, |
{2{vram_src_mask_shift[4] }}, |
{2{vram_src_mask_shift[2] }}, |
{2{vram_src_mask_shift[0] }}}) | |
({16{gfx_mode_4_bpp }} & {{4{vram_src_mask_shift[12]}}, |
{4{vram_src_mask_shift[8] }}, |
{4{vram_src_mask_shift[4] }}, |
{4{vram_src_mask_shift[0] }}}) | |
({16{gfx_mode_8_bpp }} & {{8{vram_src_mask_shift[8] }}, |
{8{vram_src_mask_shift[0] }}}) | |
({16{gfx_mode_16_bpp}} & {16{1'b1}} ) ; |
|
wire [15:0] vram_src_mask_fill_nxt = ({16{gfx_mode_1_bpp }} & 16'h0001) | |
({16{gfx_mode_2_bpp }} & 16'h0003) | |
({16{gfx_mode_4_bpp }} & 16'h000f) | |
({16{gfx_mode_8_bpp }} & 16'h00ff) | |
({16{gfx_mode_16_bpp}} & 16'hffff) ; |
|
wire [15:0] vram_src_mask_nxt = exec_fill_i ? vram_src_mask_fill_nxt : |
vram_src_mask_vram_nxt ; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) vram_src_mask <= 16'h0000; |
else if (trig_exec_i | vram_src_addr_inc) vram_src_mask <= vram_src_mask_nxt; |
|
|
//============================================================================= |
// 6) DESTINATION ADDRESS GENERATION |
//============================================================================= |
|
reg [`APIX_MSB:0] vram_dst_addr; |
wire [`APIX_MSB:0] vram_dst_addr_calc; |
|
wire vram_dst_addr_inc = dma_pixel_done; |
wire [`APIX_MSB:0] vram_dst_addr_nxt = trig_exec_i ? cfg_dst_px_addr_i : vram_dst_addr_calc; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) vram_dst_addr <= {`APIX_MSB+1{1'b0}}; |
else if (trig_exec_i | vram_dst_addr_inc) vram_dst_addr <= vram_dst_addr_nxt; |
|
|
// Compute the next address |
ogfx_gpu_dma_addr ogfx_gpu_dma_dst_addr_inst ( |
|
// OUTPUTs |
.vid_ram_addr_nxt_o ( vram_dst_addr_calc ), // Next Video-RAM address |
|
// INPUTs |
.mclk ( mclk ), // Main system clock |
.puc_rst ( puc_rst ), // Main system reset |
.display_width_i ( display_width_i ), // Display width |
.gfx_mode_1_bpp_i ( gfx_mode_1_bpp ), // Graphic mode 1 bpp resolution |
.gfx_mode_2_bpp_i ( gfx_mode_2_bpp ), // Graphic mode 2 bpp resolution |
.gfx_mode_4_bpp_i ( gfx_mode_4_bpp ), // Graphic mode 4 bpp resolution |
.gfx_mode_8_bpp_i ( gfx_mode_8_bpp ), // Graphic mode 8 bpp resolution |
.gfx_mode_16_bpp_i ( gfx_mode_16_bpp ), // Graphic mode 16 bpp resolution |
.vid_ram_addr_i ( vram_dst_addr ), // Video-RAM address |
.vid_ram_addr_init_i ( dma_init ), // Video-RAM address initialization |
.vid_ram_addr_step_i ( vram_dst_addr_inc ), // Video-RAM address step |
.vid_ram_width_i ( cfg_rec_width_i ), // Video-RAM width |
.vid_ram_win_x_swap_i ( cfg_dst_x_swp_i ), // Video-RAM X-Swap configuration |
.vid_ram_win_y_swap_i ( cfg_dst_y_swp_i ), // Video-RAM Y-Swap configuration |
.vid_ram_win_cl_swap_i ( cfg_dst_cl_swp_i ) // Video-RAM CL-Swap configuration |
); |
|
//============================================================================= |
// 7) DESTINATION DATA MASK |
//============================================================================= |
|
reg [15:0] vram_dst_mask; |
wire [15:0] vram_dst_mask_shift = one_hot16(vram_dst_addr_nxt[3:0]); |
wire [15:0] vram_dst_mask_nxt = ({16{gfx_mode_1_bpp }} & vram_dst_mask_shift ) | |
({16{gfx_mode_2_bpp }} & {{2{vram_dst_mask_shift[14]}}, |
{2{vram_dst_mask_shift[12]}}, |
{2{vram_dst_mask_shift[10]}}, |
{2{vram_dst_mask_shift[8] }}, |
{2{vram_dst_mask_shift[6] }}, |
{2{vram_dst_mask_shift[4] }}, |
{2{vram_dst_mask_shift[2] }}, |
{2{vram_dst_mask_shift[0] }}}) | |
({16{gfx_mode_4_bpp }} & {{4{vram_dst_mask_shift[12]}}, |
{4{vram_dst_mask_shift[8] }}, |
{4{vram_dst_mask_shift[4] }}, |
{4{vram_dst_mask_shift[0] }}}) | |
({16{gfx_mode_8_bpp }} & {{8{vram_dst_mask_shift[8] }}, |
{8{vram_dst_mask_shift[0] }}}) | |
({16{gfx_mode_16_bpp}} & {16{1'b1}} ) ; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) vram_dst_mask <= 16'h0000; |
else if (trig_exec_i | vram_dst_addr_inc) vram_dst_mask <= vram_dst_mask_nxt; |
|
|
//============================================================================= |
// 8) VIDEO-MEMORY INTERFACE |
//============================================================================= |
|
//-------------------------- |
// Source data |
//-------------------------- |
|
// Align source data to destination for lower resolution |
wire [15:0] src_data_mask = ((exec_fill_i ? cfg_fill_color_i : vid_ram_dout_i) & vram_src_mask); |
wire src_data_mask_1_bpp = (|src_data_mask); |
wire [1:0] src_data_mask_2_bpp = {(|{src_data_mask[15], src_data_mask[13], src_data_mask[11], src_data_mask[9], src_data_mask[7], src_data_mask[5], src_data_mask[3], src_data_mask[1]}), |
(|{src_data_mask[14], src_data_mask[12], src_data_mask[10], src_data_mask[8], src_data_mask[6], src_data_mask[4], src_data_mask[2], src_data_mask[0]})}; |
wire [3:0] src_data_mask_4_bpp = {(|{src_data_mask[15], src_data_mask[11], src_data_mask[7] , src_data_mask[3]}), |
(|{src_data_mask[14], src_data_mask[10], src_data_mask[6] , src_data_mask[2]}), |
(|{src_data_mask[13], src_data_mask[9] , src_data_mask[5] , src_data_mask[1]}), |
(|{src_data_mask[12], src_data_mask[8] , src_data_mask[4] , src_data_mask[0]})}; |
wire [7:0] src_data_mask_8_bpp = {(|{src_data_mask[15], src_data_mask[7]}), |
(|{src_data_mask[14], src_data_mask[6]}), |
(|{src_data_mask[13], src_data_mask[5]}), |
(|{src_data_mask[12], src_data_mask[4]}), |
(|{src_data_mask[11], src_data_mask[3]}), |
(|{src_data_mask[10], src_data_mask[2]}), |
(|{src_data_mask[9] , src_data_mask[1]}), |
(|{src_data_mask[8] , src_data_mask[0]})}; |
wire [15:0] src_data_mask_16_bpp = src_data_mask; |
|
wire [15:0] src_data_align = ({16{gfx_mode_1_bpp }} & {16{src_data_mask_1_bpp}}) | |
({16{gfx_mode_2_bpp }} & {8{src_data_mask_2_bpp}}) | |
({16{gfx_mode_4_bpp }} & {4{src_data_mask_4_bpp}}) | |
({16{gfx_mode_8_bpp }} & {2{src_data_mask_8_bpp}}) | |
({16{gfx_mode_16_bpp}} & src_data_mask_16_bpp ) ; |
|
// Detect read accesses |
reg src_data_ready; |
wire src_data_ready_nxt = ((dma_state==SRC_READ) & data_ready_nxt) | (exec_fill_i & dma_init); |
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) src_data_ready <= 1'b0; |
else src_data_ready <= src_data_ready_nxt; |
|
// Read data buffer |
reg [15:0] src_data_buf; |
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) src_data_buf <= 16'h0000; |
else if (src_data_ready) src_data_buf <= src_data_align; |
|
// Source data |
wire [15:0] src_data = src_data_ready ? src_data_align : src_data_buf; |
|
//-------------------------- |
// Destination data |
//-------------------------- |
|
// Detect read access |
reg dst_data_ready; |
wire dst_data_ready_nxt = ((dma_state==DST_READ) & data_ready_nxt); |
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) dst_data_ready <= 1'b0; |
else dst_data_ready <= dst_data_ready_nxt; |
|
// Read data buffer |
reg [15:0] dst_data_buf; |
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) dst_data_buf <= 16'h0000; |
else if (dst_data_ready) dst_data_buf <= vid_ram_dout_i; |
|
// Source data |
wire [15:0] dst_data = dst_data_ready ? vid_ram_dout_i : dst_data_buf; |
|
//-------------------------- |
// Detect transparency |
//-------------------------- |
wire [15:0] transparent_color_align = ({16{gfx_mode_1_bpp }} & {16{cfg_transparent_color_i[0] }}) | |
({16{gfx_mode_2_bpp }} & {8{cfg_transparent_color_i[1:0]}}) | |
({16{gfx_mode_4_bpp }} & {4{cfg_transparent_color_i[3:0]}}) | |
({16{gfx_mode_8_bpp }} & {2{cfg_transparent_color_i[7:0]}}) | |
({16{gfx_mode_16_bpp}} & cfg_transparent_color_i ) ; |
|
wire pixel_is_transparent_nxt = ((exec_copy_trans_i & src_data_ready ) | |
(exec_copy_i & src_data_ready & (pix_op_13 | pix_op_14 | pix_op_15)) | |
(exec_fill_i & (pix_op_13 | pix_op_14 | pix_op_15)) ) & (src_data_align==transparent_color_align); |
reg pixel_is_transparent_reg; |
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) pixel_is_transparent_reg <= 1'b0; |
else if (dma_pixel_done | (dma_state==IDLE)) pixel_is_transparent_reg <= 1'b0; |
else if (pixel_is_transparent_nxt) pixel_is_transparent_reg <= 1'b1; |
|
assign pixel_is_transparent = (pixel_is_transparent_nxt | pixel_is_transparent_reg); |
|
//-------------------------- |
// Pixel operation |
//-------------------------- |
wire [15:0] fill_color_align = ({16{gfx_mode_1_bpp }} & {16{cfg_fill_color_i[0] }}) | |
({16{gfx_mode_2_bpp }} & {8{cfg_fill_color_i[1:0]}}) | |
({16{gfx_mode_4_bpp }} & {4{cfg_fill_color_i[3:0]}}) | |
({16{gfx_mode_8_bpp }} & {2{cfg_fill_color_i[7:0]}}) | |
({16{gfx_mode_16_bpp}} & cfg_fill_color_i ) ; |
|
wire [15:0] pixel_data = ({16{pix_op_00}} & ( src_data )) | // S |
({16{pix_op_01}} & (~src_data )) | // not S |
({16{pix_op_02}} & ( ~dst_data)) | // not D |
|
({16{pix_op_03}} & ( src_data & dst_data)) | // S and D |
({16{pix_op_04}} & ( src_data | dst_data)) | // S or D |
({16{pix_op_05}} & ( src_data ^ dst_data)) | // S xor D |
|
({16{pix_op_06}} & ~( src_data & dst_data)) | // not (S and D) |
({16{pix_op_07}} & ~( src_data | dst_data)) | // not (S or D) |
({16{pix_op_08}} & ~( src_data ^ dst_data)) | // not (S xor D) |
|
({16{pix_op_09}} & (~src_data & dst_data)) | // (not S) and D |
({16{pix_op_10}} & ( src_data & ~dst_data)) | // S and (not D) |
({16{pix_op_11}} & (~src_data | dst_data)) | // (not S) or D |
({16{pix_op_12}} & ( src_data | ~dst_data)) | // S or (not D) |
|
({16{pix_op_13}} & ( 16'h0000 )) | // Fill 0 if S not transparent |
({16{pix_op_14}} & ( 16'hffff )) | // Fill 1 if S not transparent |
({16{pix_op_15}} & ( fill_color_align )) ; // Fill 'fill_color' if S not transparent |
|
|
|
// RAM interface |
assign vid_ram_din_o = (pixel_data & vram_dst_mask) | (dst_data & ~vram_dst_mask); |
|
assign vid_ram_addr_o = (dma_state==SRC_READ) ? vram_src_addr[`APIX_MSB:4] : |
vram_dst_addr[`APIX_MSB:4] ; |
|
assign vid_ram_wen_o = ~( (dma_state==DST_WRITE) & ~pixel_is_transparent) ; |
|
assign vid_ram_cen_o = ~( (dma_state==SRC_READ) | |
((dma_state==DST_READ) & ~pixel_is_transparent) | |
((dma_state==DST_WRITE) & ~pixel_is_transparent)); |
|
|
endmodule // ogfx_gpu_dma |
|
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_undefines.v" |
`endif |
/trunk/core/rtl/verilog/ogfx_reg.v
0,0 → 1,1377
//---------------------------------------------------------------------------- |
// 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_reg.v |
// |
// *Module Description: |
// Registers for oMSP programming. |
// |
// *Author(s): |
// - Olivier Girard, olgirard@gmail.com |
// |
//---------------------------------------------------------------------------- |
// $Rev$ |
// $LastChangedBy$ |
// $LastChangedDate$ |
//---------------------------------------------------------------------------- |
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_defines.v" |
`endif |
|
module ogfx_reg ( |
|
// OUTPUTs |
irq_gfx_o, // Graphic Controller interrupt |
|
gpu_data_o, // GPU data |
gpu_data_avail_o, // GPU data available |
gpu_enable_o, // GPU enable |
|
lt24_reset_n_o, // LT24 Reset (Active Low) |
lt24_on_o, // LT24 on/off |
lt24_cfg_clk_o, // LT24 Interface clock configuration |
lt24_cfg_refr_o, // LT24 Interface refresh configuration |
lt24_cfg_refr_sync_en_o, // LT24 Interface refresh sync enable configuration |
lt24_cfg_refr_sync_val_o, // LT24 Interface refresh sync value configuration |
lt24_cmd_refr_o, // LT24 Interface refresh command |
lt24_cmd_val_o, // LT24 Generic command value |
lt24_cmd_has_param_o, // LT24 Generic command has parameters |
lt24_cmd_param_o, // LT24 Generic command parameter value |
lt24_cmd_param_rdy_o, // LT24 Generic command trigger |
lt24_cmd_dfill_o, // LT24 Data fill value |
lt24_cmd_dfill_wr_o, // LT24 Data fill trigger |
|
display_width_o, // Display width |
display_height_o, // Display height |
display_size_o, // Display size (number of pixels) |
display_y_swap_o, // Display configuration: swap Y axis (horizontal symmetry) |
display_x_swap_o, // Display configuration: swap X axis (vertical symmetry) |
display_cl_swap_o, // Display configuration: swap column/lines |
gfx_mode_o, // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp) |
|
per_dout_o, // Peripheral data output |
|
refresh_frame_addr_o, // Refresh frame base address |
refresh_lut_select_o, // Refresh LUT bank selection |
|
`ifdef WITH_PROGRAMMABLE_LUT |
lut_ram_addr_o, // LUT-RAM address |
lut_ram_din_o, // LUT-RAM data |
lut_ram_wen_o, // LUT-RAM write strobe (active low) |
lut_ram_cen_o, // LUT-RAM chip enable (active low) |
`endif |
|
vid_ram_addr_o, // Video-RAM address |
vid_ram_din_o, // Video-RAM data |
vid_ram_wen_o, // Video-RAM write strobe (active low) |
vid_ram_cen_o, // Video-RAM chip enable (active low) |
|
// INPUTs |
dbg_freeze_i, // Freeze address auto-incr on read |
gpu_cmd_done_evt_i, // GPU command done event |
gpu_cmd_error_evt_i, // GPU command error event |
gpu_get_data_i, // GPU get next data |
lt24_status_i, // LT24 FSM Status |
lt24_start_evt_i, // LT24 FSM is starting |
lt24_done_evt_i, // LT24 FSM is done |
mclk, // Main system clock |
per_addr_i, // Peripheral address |
per_din_i, // Peripheral data input |
per_en_i, // Peripheral enable (high active) |
per_we_i, // Peripheral write enable (high active) |
puc_rst, // Main system reset |
`ifdef WITH_PROGRAMMABLE_LUT |
lut_ram_dout_i, // LUT-RAM data input |
`endif |
vid_ram_dout_i // Video-RAM data input |
); |
|
// OUTPUTs |
//========= |
output irq_gfx_o; // Graphic Controller interrupt |
|
output [15:0] gpu_data_o; // GPU data |
output gpu_data_avail_o; // GPU data available |
output gpu_enable_o; // GPU enable |
|
output lt24_reset_n_o; // LT24 Reset (Active Low) |
output lt24_on_o; // LT24 on/off |
output [2:0] lt24_cfg_clk_o; // LT24 Interface clock configuration |
output [11:0] lt24_cfg_refr_o; // LT24 Interface refresh configuration |
output lt24_cfg_refr_sync_en_o; // LT24 Interface refresh sync configuration |
output [9:0] lt24_cfg_refr_sync_val_o; // LT24 Interface refresh sync value configuration |
output lt24_cmd_refr_o; // LT24 Interface refresh command |
output [7:0] lt24_cmd_val_o; // LT24 Generic command value |
output lt24_cmd_has_param_o; // LT24 Generic command has parameters |
output [15:0] lt24_cmd_param_o; // LT24 Generic command parameter value |
output lt24_cmd_param_rdy_o; // LT24 Generic command trigger |
output [15:0] lt24_cmd_dfill_o; // LT24 Data fill value |
output lt24_cmd_dfill_wr_o; // LT24 Data fill trigger |
|
output [`LPIX_MSB:0] display_width_o; // Display width |
output [`LPIX_MSB:0] display_height_o; // Display height |
output [`SPIX_MSB:0] display_size_o; // Display size (number of pixels) |
output display_y_swap_o; // Display configuration: swap Y axis (horizontal symmetry) |
output display_x_swap_o; // Display configuration: swap X axis (vertical symmetry) |
output display_cl_swap_o; // Display configuration: swap column/lines |
output [2:0] gfx_mode_o; // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp) |
|
output [15:0] per_dout_o; // Peripheral data output |
|
output [`APIX_MSB:0] refresh_frame_addr_o; // Refresh frame base address |
output [1:0] refresh_lut_select_o; // Refresh LUT bank selection |
|
`ifdef WITH_PROGRAMMABLE_LUT |
output [`LRAM_MSB:0] lut_ram_addr_o; // LUT-RAM address |
output [15:0] lut_ram_din_o; // LUT-RAM data |
output lut_ram_wen_o; // LUT-RAM write strobe (active low) |
output lut_ram_cen_o; // LUT-RAM chip enable (active low) |
`endif |
|
output [`VRAM_MSB:0] vid_ram_addr_o; // Video-RAM address |
output [15:0] vid_ram_din_o; // Video-RAM data |
output vid_ram_wen_o; // Video-RAM write strobe (active low) |
output vid_ram_cen_o; // Video-RAM chip enable (active low) |
|
// INPUTs |
//========= |
input dbg_freeze_i; // Freeze address auto-incr on read |
input gpu_cmd_done_evt_i; // GPU command done event |
input gpu_cmd_error_evt_i; // GPU command error event |
input gpu_get_data_i; // GPU get next data |
input [4:0] lt24_status_i; // LT24 FSM Status |
input lt24_start_evt_i; // LT24 FSM is starting |
input lt24_done_evt_i; // LT24 FSM is done |
input mclk; // Main system clock |
input [13:0] per_addr_i; // Peripheral address |
input [15:0] per_din_i; // Peripheral data input |
input per_en_i; // Peripheral enable (high active) |
input [1:0] per_we_i; // Peripheral write enable (high active) |
input puc_rst; // Main system reset |
`ifdef WITH_PROGRAMMABLE_LUT |
input [15:0] lut_ram_dout_i; // LUT-RAM data input |
`endif |
input [15:0] vid_ram_dout_i; // Video-RAM data input |
|
|
//============================================================================= |
// 1) PARAMETER DECLARATION |
//============================================================================= |
|
// Register base address (must be aligned to decoder bit width) |
parameter [14:0] BASE_ADDR = 15'h0200; |
|
// Decoder bit width (defines how many bits are considered for address decoding) |
parameter DEC_WD = 7; |
|
// Register addresses offset |
parameter [DEC_WD-1:0] GFX_CTRL = 'h00, // General control/status/irq |
GFX_STATUS = 'h08, |
GFX_IRQ = 'h0A, |
|
DISPLAY_WIDTH = 'h10, // Display configuration |
DISPLAY_HEIGHT = 'h12, |
DISPLAY_SIZE_HI = 'h14, |
DISPLAY_SIZE_LO = 'h16, |
DISPLAY_CFG = 'h18, |
|
LT24_CFG = 'h20, // LT24 configuration and Generic command sending |
LT24_REFRESH = 'h22, |
LT24_REFRESH_SYNC = 'h24, |
LT24_CMD = 'h26, |
LT24_CMD_PARAM = 'h28, |
LT24_CMD_DFILL = 'h2A, |
LT24_STATUS = 'h2C, |
|
LUT_RAM_ADDR = 'h30, // LUT Memory Access Gate |
LUT_RAM_DATA = 'h32, |
|
FRAME_SELECT = 'h3E, // Frame pointers and selection |
FRAME0_PTR_HI = 'h40, |
FRAME0_PTR_LO = 'h42, |
FRAME1_PTR_HI = 'h44, |
FRAME1_PTR_LO = 'h46, |
FRAME2_PTR_HI = 'h48, |
FRAME2_PTR_LO = 'h4A, |
FRAME3_PTR_HI = 'h4C, |
FRAME3_PTR_LO = 'h4E, |
|
VID_RAM0_CFG = 'h50, // First Video Memory Access Gate |
VID_RAM0_WIDTH = 'h52, |
VID_RAM0_ADDR_HI = 'h54, |
VID_RAM0_ADDR_LO = 'h56, |
VID_RAM0_DATA = 'h58, |
|
VID_RAM1_CFG = 'h60, // Second Video Memory Access Gate |
VID_RAM1_WIDTH = 'h62, |
VID_RAM1_ADDR_HI = 'h64, |
VID_RAM1_ADDR_LO = 'h66, |
VID_RAM1_DATA = 'h68, |
|
GPU_CMD = 'h70, // Graphic Processing Unit |
GPU_STAT = 'h72; |
|
|
// Register one-hot decoder utilities |
parameter DEC_SZ = (1 << DEC_WD); |
parameter [DEC_SZ-1:0] BASE_REG = {{DEC_SZ-1{1'b0}}, 1'b1}; |
|
// Register one-hot decoder |
parameter [DEC_SZ-1:0] GFX_CTRL_D = (BASE_REG << GFX_CTRL ), |
GFX_STATUS_D = (BASE_REG << GFX_STATUS ), |
GFX_IRQ_D = (BASE_REG << GFX_IRQ ), |
|
DISPLAY_WIDTH_D = (BASE_REG << DISPLAY_WIDTH ), |
DISPLAY_HEIGHT_D = (BASE_REG << DISPLAY_HEIGHT ), |
DISPLAY_SIZE_HI_D = (BASE_REG << DISPLAY_SIZE_HI ), |
DISPLAY_SIZE_LO_D = (BASE_REG << DISPLAY_SIZE_LO ), |
DISPLAY_CFG_D = (BASE_REG << DISPLAY_CFG ), |
|
LT24_CFG_D = (BASE_REG << LT24_CFG ), |
LT24_REFRESH_D = (BASE_REG << LT24_REFRESH ), |
LT24_REFRESH_SYNC_D = (BASE_REG << LT24_REFRESH_SYNC ), |
LT24_CMD_D = (BASE_REG << LT24_CMD ), |
LT24_CMD_PARAM_D = (BASE_REG << LT24_CMD_PARAM ), |
LT24_CMD_DFILL_D = (BASE_REG << LT24_CMD_DFILL ), |
LT24_STATUS_D = (BASE_REG << LT24_STATUS ), |
|
LUT_RAM_ADDR_D = (BASE_REG << LUT_RAM_ADDR ), |
LUT_RAM_DATA_D = (BASE_REG << LUT_RAM_DATA ), |
|
FRAME_SELECT_D = (BASE_REG << FRAME_SELECT ), |
FRAME0_PTR_HI_D = (BASE_REG << FRAME0_PTR_HI ), |
FRAME0_PTR_LO_D = (BASE_REG << FRAME0_PTR_LO ), |
FRAME1_PTR_HI_D = (BASE_REG << FRAME1_PTR_HI ), |
FRAME1_PTR_LO_D = (BASE_REG << FRAME1_PTR_LO ), |
FRAME2_PTR_HI_D = (BASE_REG << FRAME2_PTR_HI ), |
FRAME2_PTR_LO_D = (BASE_REG << FRAME2_PTR_LO ), |
FRAME3_PTR_HI_D = (BASE_REG << FRAME3_PTR_HI ), |
FRAME3_PTR_LO_D = (BASE_REG << FRAME3_PTR_LO ), |
|
VID_RAM0_CFG_D = (BASE_REG << VID_RAM0_CFG ), |
VID_RAM0_WIDTH_D = (BASE_REG << VID_RAM0_WIDTH ), |
VID_RAM0_ADDR_HI_D = (BASE_REG << VID_RAM0_ADDR_HI ), |
VID_RAM0_ADDR_LO_D = (BASE_REG << VID_RAM0_ADDR_LO ), |
VID_RAM0_DATA_D = (BASE_REG << VID_RAM0_DATA ), |
|
VID_RAM1_CFG_D = (BASE_REG << VID_RAM1_CFG ), |
VID_RAM1_WIDTH_D = (BASE_REG << VID_RAM1_WIDTH ), |
VID_RAM1_ADDR_HI_D = (BASE_REG << VID_RAM1_ADDR_HI ), |
VID_RAM1_ADDR_LO_D = (BASE_REG << VID_RAM1_ADDR_LO ), |
VID_RAM1_DATA_D = (BASE_REG << VID_RAM1_DATA ), |
|
GPU_CMD_D = (BASE_REG << GPU_CMD ), |
GPU_STAT_D = (BASE_REG << GPU_STAT ); |
|
|
//============================================================================ |
// 2) REGISTER DECODER |
//============================================================================ |
|
// Local register selection |
wire reg_sel = per_en_i & (per_addr_i[13:DEC_WD-1]==BASE_ADDR[14:DEC_WD]); |
|
// Register local address |
wire [DEC_WD-1:0] reg_addr = {per_addr_i[DEC_WD-2:0], 1'b0}; |
|
// Register address decode |
wire [DEC_SZ-1:0] reg_dec = (GFX_CTRL_D & {DEC_SZ{(reg_addr == GFX_CTRL )}}) | |
(GFX_STATUS_D & {DEC_SZ{(reg_addr == GFX_STATUS )}}) | |
(GFX_IRQ_D & {DEC_SZ{(reg_addr == GFX_IRQ )}}) | |
|
(DISPLAY_WIDTH_D & {DEC_SZ{(reg_addr == DISPLAY_WIDTH )}}) | |
(DISPLAY_HEIGHT_D & {DEC_SZ{(reg_addr == DISPLAY_HEIGHT )}}) | |
(DISPLAY_SIZE_HI_D & {DEC_SZ{(reg_addr == DISPLAY_SIZE_HI )}}) | |
(DISPLAY_SIZE_LO_D & {DEC_SZ{(reg_addr == DISPLAY_SIZE_LO )}}) | |
(DISPLAY_CFG_D & {DEC_SZ{(reg_addr == DISPLAY_CFG )}}) | |
|
(LT24_CFG_D & {DEC_SZ{(reg_addr == LT24_CFG )}}) | |
(LT24_REFRESH_D & {DEC_SZ{(reg_addr == LT24_REFRESH )}}) | |
(LT24_REFRESH_SYNC_D & {DEC_SZ{(reg_addr == LT24_REFRESH_SYNC )}}) | |
(LT24_CMD_D & {DEC_SZ{(reg_addr == LT24_CMD )}}) | |
(LT24_CMD_PARAM_D & {DEC_SZ{(reg_addr == LT24_CMD_PARAM )}}) | |
(LT24_CMD_DFILL_D & {DEC_SZ{(reg_addr == LT24_CMD_DFILL )}}) | |
(LT24_STATUS_D & {DEC_SZ{(reg_addr == LT24_STATUS )}}) | |
|
(LUT_RAM_ADDR_D & {DEC_SZ{(reg_addr == LUT_RAM_ADDR )}}) | |
(LUT_RAM_DATA_D & {DEC_SZ{(reg_addr == LUT_RAM_DATA )}}) | |
|
(FRAME_SELECT_D & {DEC_SZ{(reg_addr == FRAME_SELECT )}}) | |
(FRAME0_PTR_HI_D & {DEC_SZ{(reg_addr == FRAME0_PTR_HI )}}) | |
(FRAME0_PTR_LO_D & {DEC_SZ{(reg_addr == FRAME0_PTR_LO )}}) | |
(FRAME1_PTR_HI_D & {DEC_SZ{(reg_addr == FRAME1_PTR_HI )}}) | |
(FRAME1_PTR_LO_D & {DEC_SZ{(reg_addr == FRAME1_PTR_LO )}}) | |
(FRAME2_PTR_HI_D & {DEC_SZ{(reg_addr == FRAME2_PTR_HI )}}) | |
(FRAME2_PTR_LO_D & {DEC_SZ{(reg_addr == FRAME2_PTR_LO )}}) | |
(FRAME3_PTR_HI_D & {DEC_SZ{(reg_addr == FRAME3_PTR_HI )}}) | |
(FRAME3_PTR_LO_D & {DEC_SZ{(reg_addr == FRAME3_PTR_LO )}}) | |
|
(VID_RAM0_CFG_D & {DEC_SZ{(reg_addr == VID_RAM0_CFG )}}) | |
(VID_RAM0_WIDTH_D & {DEC_SZ{(reg_addr == VID_RAM0_WIDTH )}}) | |
(VID_RAM0_ADDR_HI_D & {DEC_SZ{(reg_addr == VID_RAM0_ADDR_HI )}}) | |
(VID_RAM0_ADDR_LO_D & {DEC_SZ{(reg_addr == VID_RAM0_ADDR_LO )}}) | |
(VID_RAM0_DATA_D & {DEC_SZ{(reg_addr == VID_RAM0_DATA )}}) | |
|
(VID_RAM1_CFG_D & {DEC_SZ{(reg_addr == VID_RAM1_CFG )}}) | |
(VID_RAM1_WIDTH_D & {DEC_SZ{(reg_addr == VID_RAM1_WIDTH )}}) | |
(VID_RAM1_ADDR_HI_D & {DEC_SZ{(reg_addr == VID_RAM1_ADDR_HI )}}) | |
(VID_RAM1_ADDR_LO_D & {DEC_SZ{(reg_addr == VID_RAM1_ADDR_LO )}}) | |
(VID_RAM1_DATA_D & {DEC_SZ{(reg_addr == VID_RAM1_DATA )}}) | |
|
(GPU_CMD_D & {DEC_SZ{(reg_addr == GPU_CMD )}}) | |
(GPU_STAT_D & {DEC_SZ{(reg_addr == GPU_STAT )}}); |
|
// Read/Write probes |
wire reg_write = |per_we_i & reg_sel; |
wire reg_read = ~|per_we_i & reg_sel; |
|
// Read/Write vectors |
wire [DEC_SZ-1:0] reg_wr = reg_dec & {DEC_SZ{reg_write}}; |
wire [DEC_SZ-1:0] reg_rd = reg_dec & {DEC_SZ{reg_read}}; |
|
// Other wire declarations |
wire [`APIX_MSB:0] frame0_ptr; |
`ifdef WITH_FRAME1_POINTER |
wire [`APIX_MSB:0] frame1_ptr; |
`endif |
`ifdef WITH_FRAME2_POINTER |
wire [`APIX_MSB:0] frame2_ptr; |
`endif |
`ifdef WITH_FRAME3_POINTER |
wire [`APIX_MSB:0] frame3_ptr; |
`endif |
wire [`APIX_MSB:0] vid_ram0_base_addr; |
wire [`APIX_MSB:0] vid_ram1_base_addr; |
`ifdef WITH_EXTRA_LUT_BANK |
reg lut_bank_select; |
`endif |
reg vid_ram0_addr_lo_wr_dly; |
reg vid_ram1_addr_lo_wr_dly; |
wire gpu_fifo_done_evt; |
wire gpu_fifo_ovfl_evt; |
|
|
//============================================================================ |
// 3) REGISTERS |
//============================================================================ |
|
//------------------------------------------------ |
// GFX_CTRL Register |
//------------------------------------------------ |
reg [15:0] gfx_ctrl; |
|
wire gfx_ctrl_wr = reg_wr[GFX_CTRL]; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) gfx_ctrl <= 16'h0000; |
else if (gfx_ctrl_wr) gfx_ctrl <= per_din_i; |
|
// Bitfield assignments |
wire gfx_irq_refr_done_en = gfx_ctrl[0]; |
wire gfx_irq_refr_start_en = gfx_ctrl[1]; |
wire gfx_irq_gpu_fifo_done_en = gfx_ctrl[4]; |
wire gfx_irq_gpu_fifo_ovfl_en = gfx_ctrl[5]; |
wire gfx_irq_gpu_cmd_done_en = gfx_ctrl[6]; |
wire gfx_irq_gpu_cmd_error_en = gfx_ctrl[7]; |
assign gfx_mode_o = gfx_ctrl[10:8]; // 1xx: 16 bits-per-pixel |
// 011: 8 bits-per-pixel |
// 010: 4 bits-per-pixel |
// 001: 2 bits-per-pixel |
// 000: 1 bits-per-pixel |
wire gpu_enable_o = gfx_ctrl[12]; |
|
// Video modes decoding |
wire gfx_mode_1_bpp = (gfx_mode_o == 3'b000); |
wire gfx_mode_2_bpp = (gfx_mode_o == 3'b001); |
wire gfx_mode_4_bpp = (gfx_mode_o == 3'b010); |
wire gfx_mode_8_bpp = (gfx_mode_o == 3'b011); |
wire gfx_mode_16_bpp = ~(gfx_mode_8_bpp | gfx_mode_4_bpp | gfx_mode_2_bpp | gfx_mode_1_bpp); |
|
//------------------------------------------------ |
// GFX_STATUS Register |
//------------------------------------------------ |
wire [15:0] gfx_status; |
|
assign gfx_status[0] = lt24_status_i[2]; // Screen Refresh is busy |
assign gfx_status[15:1] = 15'h0000; |
|
//------------------------------------------------ |
// GFX_IRQ Register |
//------------------------------------------------ |
wire [15:0] gfx_irq; |
|
// Clear IRQ when 1 is written. Set IRQ when FSM is done |
wire gfx_irq_refr_done_clr = per_din_i[0] & reg_wr[GFX_IRQ]; |
wire gfx_irq_refr_done_set = lt24_done_evt_i; |
|
wire gfx_irq_refr_start_clr = per_din_i[1] & reg_wr[GFX_IRQ]; |
wire gfx_irq_refr_start_set = lt24_start_evt_i; |
|
wire gfx_irq_gpu_fifo_done_clr = per_din_i[4] & reg_wr[GFX_IRQ]; |
wire gfx_irq_gpu_fifo_done_set = gpu_fifo_done_evt; |
|
wire gfx_irq_gpu_fifo_ovfl_clr = per_din_i[5] & reg_wr[GFX_IRQ]; |
wire gfx_irq_gpu_fifo_ovfl_set = gpu_fifo_ovfl_evt; |
|
wire gfx_irq_gpu_cmd_done_clr = per_din_i[6] & reg_wr[GFX_IRQ]; |
wire gfx_irq_gpu_cmd_done_set = gpu_cmd_done_evt_i; |
|
wire gfx_irq_gpu_cmd_error_clr = per_din_i[7] & reg_wr[GFX_IRQ]; |
wire gfx_irq_gpu_cmd_error_set = gpu_cmd_error_evt_i; |
|
reg gfx_irq_refr_done; |
reg gfx_irq_refr_start; |
reg gfx_irq_gpu_fifo_done; |
reg gfx_irq_gpu_fifo_ovfl; |
reg gfx_irq_gpu_cmd_done; |
reg gfx_irq_gpu_cmd_error; |
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) |
begin |
gfx_irq_refr_done <= 1'b0; |
gfx_irq_refr_start <= 1'b0; |
gfx_irq_gpu_fifo_done <= 1'b0; |
gfx_irq_gpu_fifo_ovfl <= 1'b0; |
gfx_irq_gpu_cmd_done <= 1'b0; |
gfx_irq_gpu_cmd_error <= 1'b0; |
end |
else |
begin |
gfx_irq_refr_done <= (gfx_irq_refr_done_set | (~gfx_irq_refr_done_clr & gfx_irq_refr_done )); // IRQ set has priority over clear |
gfx_irq_refr_start <= (gfx_irq_refr_start_set | (~gfx_irq_refr_start_clr & gfx_irq_refr_start )); // IRQ set has priority over clear |
gfx_irq_gpu_fifo_done <= (gfx_irq_gpu_fifo_done_set | (~gfx_irq_gpu_fifo_done_clr & gfx_irq_gpu_fifo_done)); // IRQ set has priority over clear |
gfx_irq_gpu_fifo_ovfl <= (gfx_irq_gpu_fifo_ovfl_set | (~gfx_irq_gpu_fifo_ovfl_clr & gfx_irq_gpu_fifo_ovfl)); // IRQ set has priority over clear |
gfx_irq_gpu_cmd_done <= (gfx_irq_gpu_cmd_done_set | (~gfx_irq_gpu_cmd_done_clr & gfx_irq_gpu_cmd_done )); // IRQ set has priority over clear |
gfx_irq_gpu_cmd_error <= (gfx_irq_gpu_cmd_error_set | (~gfx_irq_gpu_cmd_error_clr & gfx_irq_gpu_cmd_error)); // IRQ set has priority over clear |
end |
|
assign gfx_irq = {8'h00, |
gfx_irq_gpu_cmd_error, gfx_irq_gpu_cmd_done, gfx_irq_gpu_fifo_ovfl, gfx_irq_gpu_fifo_done, |
2'h0, gfx_irq_refr_start, gfx_irq_refr_done}; |
|
assign irq_gfx_o = (gfx_irq_refr_done & gfx_irq_refr_done_en) | |
(gfx_irq_refr_start & gfx_irq_refr_start_en) | |
(gfx_irq_gpu_cmd_error & gfx_irq_gpu_cmd_error_en) | |
(gfx_irq_gpu_cmd_done & gfx_irq_gpu_cmd_done_en) | |
(gfx_irq_gpu_fifo_ovfl & gfx_irq_gpu_fifo_ovfl_en) | |
(gfx_irq_gpu_fifo_done & gfx_irq_gpu_fifo_done_en); // Graphic Controller interrupt |
|
//------------------------------------------------ |
// DISPLAY_WIDTH Register |
//------------------------------------------------ |
reg [`LPIX_MSB:0] display_width_o; |
|
wire display_width_wr = reg_wr[DISPLAY_WIDTH]; |
wire [`LPIX_MSB:0] display_w_h_nxt = (|per_din_i[`LPIX_MSB:0]) ? per_din_i[`LPIX_MSB:0] : |
{{`LPIX_MSB{1'b0}}, 1'b1}; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) display_width_o <= {{`LPIX_MSB{1'b0}}, 1'b1}; |
else if (display_width_wr) display_width_o <= display_w_h_nxt; |
|
wire [16:0] display_width_tmp = {{16-`LPIX_MSB{1'b0}}, display_width_o}; |
wire [15:0] display_width_rd = display_width_tmp[15:0]; |
|
//------------------------------------------------ |
// DISPLAY_HEIGHT Register |
//------------------------------------------------ |
reg [`LPIX_MSB:0] display_height_o; |
|
wire display_height_wr = reg_wr[DISPLAY_HEIGHT]; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) display_height_o <= {{`LPIX_MSB{1'b0}}, 1'b1}; |
else if (display_height_wr) display_height_o <= display_w_h_nxt; |
|
wire [16:0] display_height_tmp = {{16-`LPIX_MSB{1'b0}}, display_height_o}; |
wire [15:0] display_height_rd = display_height_tmp[15:0]; |
|
//------------------------------------------------ |
// DISPLAY_SIZE_HI Register |
//------------------------------------------------ |
`ifdef WITH_DISPLAY_SIZE_HI |
reg [`SPIX_HI_MSB:0] display_size_hi; |
|
wire display_size_hi_wr = reg_wr[DISPLAY_SIZE_HI]; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) display_size_hi <= {`SPIX_HI_MSB+1{1'h0}}; |
else if (display_size_hi_wr) display_size_hi <= per_din_i[`SPIX_HI_MSB:0]; |
|
wire [16:0] display_size_hi_tmp = {{16-`SPIX_HI_MSB{1'h0}}, display_size_hi}; |
wire [15:0] display_size_hi_rd = display_size_hi_tmp[15:0]; |
`endif |
|
//------------------------------------------------ |
// DISPLAY_SIZE_LO Register |
//------------------------------------------------ |
reg [`SPIX_LO_MSB:0] display_size_lo; |
|
wire display_size_lo_wr = reg_wr[DISPLAY_SIZE_LO]; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) display_size_lo <= {{`SPIX_LO_MSB{1'h0}}, 1'b1}; |
else if (display_size_lo_wr) display_size_lo <= per_din_i[`SPIX_LO_MSB:0]; |
|
wire [16:0] display_size_lo_tmp = {{16-`SPIX_LO_MSB{1'h0}}, display_size_lo}; |
wire [15:0] display_size_lo_rd = display_size_lo_tmp[15:0]; |
|
`ifdef WITH_DISPLAY_SIZE_HI |
assign display_size_o = {display_size_hi, display_size_lo}; |
`else |
assign display_size_o = display_size_lo; |
`endif |
|
//------------------------------------------------ |
// DISPLAY_CFG Register |
//------------------------------------------------ |
reg display_x_swap_o; |
reg display_y_swap_o; |
reg display_cl_swap_o; |
|
wire display_cfg_wr = reg_wr[DISPLAY_CFG]; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) |
begin |
display_cl_swap_o <= 1'b0; |
display_y_swap_o <= 1'b0; |
display_x_swap_o <= 1'b0; |
end |
else if (display_cfg_wr) |
begin |
display_cl_swap_o <= per_din_i[0]; |
display_y_swap_o <= per_din_i[1]; |
display_x_swap_o <= per_din_i[2]; |
end |
|
wire [15:0] display_cfg = {13'h0000, |
display_x_swap_o, |
display_y_swap_o, |
display_cl_swap_o}; |
|
//------------------------------------------------ |
// LT24_CFG Register |
//------------------------------------------------ |
reg [15:0] lt24_cfg; |
|
wire lt24_cfg_wr = reg_wr[LT24_CFG]; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) lt24_cfg <= 16'h0000; |
else if (lt24_cfg_wr) lt24_cfg <= per_din_i; |
|
// Bitfield assignments |
assign lt24_cfg_clk_o = lt24_cfg[6:4]; |
assign lt24_reset_n_o = ~lt24_cfg[1]; |
assign lt24_on_o = lt24_cfg[0]; |
|
//------------------------------------------------ |
// LT24_REFRESH Register |
//------------------------------------------------ |
reg lt24_cmd_refr_o; |
reg [11:0] lt24_cfg_refr_o; |
|
wire lt24_refresh_wr = reg_wr[LT24_REFRESH]; |
wire lt24_cmd_refr_clr = lt24_done_evt_i & lt24_status_i[2] & (lt24_cfg_refr_o==8'h00); // Auto-clear in manual refresh mode when done |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) lt24_cmd_refr_o <= 1'h0; |
else if (lt24_refresh_wr) lt24_cmd_refr_o <= per_din_i[0]; |
else if (lt24_cmd_refr_clr) lt24_cmd_refr_o <= 1'h0; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) lt24_cfg_refr_o <= 12'h000; |
else if (lt24_refresh_wr) lt24_cfg_refr_o <= per_din_i[15:4]; |
|
wire [15:0] lt24_refresh = {lt24_cfg_refr_o, 3'h0, lt24_cmd_refr_o}; |
|
//------------------------------------------------ |
// LT24_REFRESH Register |
//------------------------------------------------ |
reg lt24_cfg_refr_sync_en_o; |
reg [9:0] lt24_cfg_refr_sync_val_o; |
|
wire lt24_refresh_sync_wr = reg_wr[LT24_REFRESH_SYNC]; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) lt24_cfg_refr_sync_en_o <= 1'h0; |
else if (lt24_refresh_sync_wr) lt24_cfg_refr_sync_en_o <= per_din_i[15]; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) lt24_cfg_refr_sync_val_o <= 10'h000; |
else if (lt24_refresh_sync_wr) lt24_cfg_refr_sync_val_o <= per_din_i[9:0]; |
|
wire [15:0] lt24_refresh_sync = {lt24_cfg_refr_sync_en_o, 5'h00, lt24_cfg_refr_sync_val_o}; |
|
|
//------------------------------------------------ |
// LT24_CMD Register |
//------------------------------------------------ |
reg [15:0] lt24_cmd; |
|
wire lt24_cmd_wr = reg_wr[LT24_CMD]; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) lt24_cmd <= 16'h0000; |
else if (lt24_cmd_wr) lt24_cmd <= per_din_i; |
|
assign lt24_cmd_val_o = lt24_cmd[7:0]; |
assign lt24_cmd_has_param_o = lt24_cmd[8]; |
|
//------------------------------------------------ |
// LT24_CMD_PARAM Register |
//------------------------------------------------ |
reg [15:0] lt24_cmd_param_o; |
|
wire lt24_cmd_param_wr = reg_wr[LT24_CMD_PARAM]; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) lt24_cmd_param_o <= 16'h0000; |
else if (lt24_cmd_param_wr) lt24_cmd_param_o <= per_din_i; |
|
reg lt24_cmd_param_rdy_o; |
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) lt24_cmd_param_rdy_o <= 1'b0; |
else lt24_cmd_param_rdy_o <= lt24_cmd_param_wr; |
|
//------------------------------------------------ |
// LT24_CMD_DFILL Register |
//------------------------------------------------ |
reg [15:0] lt24_cmd_dfill_o; |
|
assign lt24_cmd_dfill_wr_o = reg_wr[LT24_CMD_DFILL]; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) lt24_cmd_dfill_o <= 16'h0000; |
else if (lt24_cmd_dfill_wr_o) lt24_cmd_dfill_o <= per_din_i; |
|
//------------------------------------------------ |
// LT24_STATUS Register |
//------------------------------------------------ |
wire [15:0] lt24_status; |
|
assign lt24_status[0] = lt24_status_i[0]; // FSM_BUSY |
assign lt24_status[1] = lt24_status_i[1]; // WAIT_PARAM |
assign lt24_status[2] = lt24_status_i[2]; // REFRESH_BUSY |
assign lt24_status[3] = lt24_status_i[3]; // WAIT_FOR_SCANLINE |
assign lt24_status[4] = lt24_status_i[4]; // DATA_FILL_BUSY |
assign lt24_status[15:5] = 11'h000; |
|
|
//------------------------------------------------ |
// LUT_RAM_ADDR Register |
//------------------------------------------------ |
`ifdef WITH_PROGRAMMABLE_LUT |
|
reg [7:0] lut_ram_addr; |
wire [7:0] lut_ram_addr_inc; |
wire lut_ram_addr_inc_wr; |
|
wire lut_ram_addr_wr = reg_wr[LUT_RAM_ADDR]; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) lut_ram_addr <= 8'h00; |
else if (lut_ram_addr_wr) lut_ram_addr <= per_din_i[7:0]; |
else if (lut_ram_addr_inc_wr) lut_ram_addr <= lut_ram_addr_inc; |
|
assign lut_ram_addr_inc = lut_ram_addr + 8'h01; |
wire [15:0] lut_ram_addr_rd = {8'h00, lut_ram_addr}; |
|
`ifdef WITH_EXTRA_LUT_BANK |
assign lut_ram_addr_o = {lut_bank_select, lut_ram_addr}; |
`else |
assign lut_ram_addr_o = lut_ram_addr; |
`endif |
|
`else |
wire [15:0] lut_ram_addr_rd = 16'h0000; |
`endif |
|
//------------------------------------------------ |
// LUT_RAM_DATA Register |
//------------------------------------------------ |
`ifdef WITH_PROGRAMMABLE_LUT |
|
// Update the LUT_RAM_DATA register with regular register write access |
wire lut_ram_data_wr = reg_wr[LUT_RAM_DATA]; |
wire lut_ram_data_rd = reg_rd[LUT_RAM_DATA]; |
reg lut_ram_dout_rdy; |
|
// LUT-RAM data Register |
reg [15:0] lut_ram_data; |
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) lut_ram_data <= 16'h0000; |
else if (lut_ram_data_wr) lut_ram_data <= per_din_i; |
else if (lut_ram_dout_rdy) lut_ram_data <= lut_ram_dout_i; |
|
// Increment the address after a write or read access to the LUT_RAM_DATA register |
assign lut_ram_addr_inc_wr = lut_ram_data_wr | lut_ram_data_rd; |
|
// Apply peripheral data bus % write strobe during VID_RAMx_DATA write access |
assign lut_ram_din_o = per_din_i & {16{lut_ram_data_wr}}; |
assign lut_ram_wen_o = ~(|per_we_i & lut_ram_data_wr); |
|
// Trigger a LUT-RAM read access immediately after: |
// - a LUT-RAM_ADDR register write access |
// - a LUT-RAM_DATA register read access |
reg lut_ram_addr_wr_dly; |
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) lut_ram_addr_wr_dly <= 1'b0; |
else lut_ram_addr_wr_dly <= lut_ram_addr_wr; |
|
reg lut_ram_data_rd_dly; |
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) lut_ram_data_rd_dly <= 1'b0; |
else lut_ram_data_rd_dly <= lut_ram_data_rd; |
|
// Chip enable. |
// Note: we perform a data read access: |
// - one cycle after a VID_RAM_DATA register read access (so that the address has been incremented) |
// - one cycle after a VID_RAM_ADDR register write |
assign lut_ram_cen_o = ~(lut_ram_addr_wr_dly | lut_ram_data_rd_dly | // Read access |
lut_ram_data_wr); // Write access |
|
// Update the VRAM_DATA register one cycle after each memory access |
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) lut_ram_dout_rdy <= 1'b0; |
else lut_ram_dout_rdy <= ~lut_ram_cen_o; |
|
`else |
wire [15:0] lut_ram_data = 16'h0000; |
`endif |
|
//------------------------------------------------ |
// FRAME_SELECT Register |
//------------------------------------------------ |
|
wire frame_select_wr = reg_wr[FRAME_SELECT]; |
|
`ifdef WITH_PROGRAMMABLE_LUT |
reg refresh_sw_lut_enable; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) refresh_sw_lut_enable <= 1'b0; |
else if (frame_select_wr) refresh_sw_lut_enable <= per_din_i[2]; |
`else |
wire refresh_sw_lut_enable = 1'b0; |
`endif |
|
`ifdef WITH_EXTRA_LUT_BANK |
reg refresh_sw_lut_select; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) |
begin |
refresh_sw_lut_select <= 1'b0; |
lut_bank_select <= 1'b0; |
end |
else if (frame_select_wr) |
begin |
refresh_sw_lut_select <= per_din_i[3]; |
lut_bank_select <= per_din_i[15]; |
end |
`else |
assign refresh_sw_lut_select = 1'b0; |
wire lut_bank_select = 1'b0; |
`endif |
wire [1:0] refresh_lut_select_o = {refresh_sw_lut_select, refresh_sw_lut_enable}; |
|
`ifdef WITH_FRAME1_POINTER |
`ifdef WITH_FRAME2_POINTER |
reg [1:0] refresh_frame_select; |
reg [1:0] vid_ram0_frame_select; |
reg [1:0] vid_ram1_frame_select; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) |
begin |
refresh_frame_select <= 2'h0; |
vid_ram0_frame_select <= 2'h0; |
vid_ram1_frame_select <= 2'h0; |
end |
else if (frame_select_wr) |
begin |
refresh_frame_select <= per_din_i[1:0]; |
vid_ram0_frame_select <= per_din_i[5:4]; |
vid_ram1_frame_select <= per_din_i[7:6]; |
end |
|
wire [15:0] frame_select = {lut_bank_select, 7'h00, vid_ram1_frame_select, vid_ram0_frame_select, refresh_lut_select_o, refresh_frame_select}; |
`else |
reg refresh_frame_select; |
reg vid_ram0_frame_select; |
reg vid_ram1_frame_select; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) |
begin |
refresh_frame_select <= 1'h0; |
vid_ram0_frame_select <= 1'h0; |
vid_ram1_frame_select <= 1'h0; |
end |
else if (frame_select_wr) |
begin |
refresh_frame_select <= per_din_i[0]; |
vid_ram0_frame_select <= per_din_i[4]; |
vid_ram1_frame_select <= per_din_i[6]; |
end |
|
wire [15:0] frame_select = {lut_bank_select, 7'h00, 1'h0, vid_ram1_frame_select, 1'h0, vid_ram0_frame_select, refresh_lut_select_o, 1'h0, refresh_frame_select}; |
`endif |
`else |
wire [15:0] frame_select = {lut_bank_select, 11'h000, refresh_lut_select_o, 2'h0}; |
`endif |
|
// Frame pointer selections |
`ifdef WITH_FRAME1_POINTER |
assign refresh_frame_addr_o = (refresh_frame_select==0) ? frame0_ptr : |
`ifdef WITH_FRAME2_POINTER |
(refresh_frame_select==1) ? frame1_ptr : |
`ifdef WITH_FRAME3_POINTER |
(refresh_frame_select==2) ? frame2_ptr : |
frame3_ptr ; |
`else |
frame2_ptr ; |
`endif |
`else |
frame1_ptr ; |
`endif |
|
assign vid_ram0_base_addr = (vid_ram0_frame_select==0) ? frame0_ptr : |
`ifdef WITH_FRAME2_POINTER |
(vid_ram0_frame_select==1) ? frame1_ptr : |
`ifdef WITH_FRAME3_POINTER |
(vid_ram0_frame_select==2) ? frame2_ptr : |
frame3_ptr ; |
`else |
frame2_ptr ; |
`endif |
`else |
frame1_ptr ; |
`endif |
|
assign vid_ram1_base_addr = (vid_ram1_frame_select==0) ? frame0_ptr : |
`ifdef WITH_FRAME2_POINTER |
(vid_ram1_frame_select==1) ? frame1_ptr : |
`ifdef WITH_FRAME3_POINTER |
(vid_ram1_frame_select==2) ? frame2_ptr : |
frame3_ptr ; |
`else |
frame2_ptr ; |
`endif |
`else |
frame1_ptr ; |
`endif |
|
`else |
assign refresh_frame_addr_o = frame0_ptr; |
assign vid_ram0_base_addr = frame0_ptr; |
assign vid_ram1_base_addr = frame0_ptr; |
`endif |
|
//------------------------------------------------ |
// FRAME0_PTR_HI Register |
//------------------------------------------------ |
`ifdef VRAM_BIGGER_4_KW |
reg [`APIX_HI_MSB:0] frame0_ptr_hi; |
|
wire frame0_ptr_hi_wr = reg_wr[FRAME0_PTR_HI]; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) frame0_ptr_hi <= {`APIX_HI_MSB+1{1'b0}}; |
else if (frame0_ptr_hi_wr) frame0_ptr_hi <= per_din_i[`APIX_HI_MSB:0]; |
|
wire [16:0] frame0_ptr_hi_tmp = {{16-`APIX_HI_MSB{1'b0}}, frame0_ptr_hi}; |
wire [15:0] frame0_ptr_hi_rd = frame0_ptr_hi_tmp[15:0]; |
`endif |
|
//------------------------------------------------ |
// FRAME0_PTR_LO Register |
//------------------------------------------------ |
reg [`APIX_LO_MSB:0] frame0_ptr_lo; |
|
wire frame0_ptr_lo_wr = reg_wr[FRAME0_PTR_LO]; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) frame0_ptr_lo <= {`APIX_LO_MSB+1{1'b0}}; |
else if (frame0_ptr_lo_wr) frame0_ptr_lo <= per_din_i[`APIX_LO_MSB:0]; |
|
`ifdef VRAM_BIGGER_4_KW |
assign frame0_ptr = {frame0_ptr_hi[`APIX_HI_MSB:0], frame0_ptr_lo}; |
wire [15:0] frame0_ptr_lo_rd = frame0_ptr_lo; |
`else |
assign frame0_ptr = {frame0_ptr_lo[`APIX_LO_MSB:0]}; |
wire [16:0] frame0_ptr_lo_tmp = {{16-`APIX_LO_MSB{1'b0}}, frame0_ptr_lo}; |
wire [15:0] frame0_ptr_lo_rd = frame0_ptr_lo_tmp[15:0]; |
`endif |
|
//------------------------------------------------ |
// FRAME1_PTR_HI Register |
//------------------------------------------------ |
`ifdef WITH_FRAME1_POINTER |
`ifdef VRAM_BIGGER_4_KW |
reg [`APIX_HI_MSB:0] frame1_ptr_hi; |
|
wire frame1_ptr_hi_wr = reg_wr[FRAME1_PTR_HI]; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) frame1_ptr_hi <= {`APIX_HI_MSB+1{1'b0}}; |
else if (frame1_ptr_hi_wr) frame1_ptr_hi <= per_din_i[`APIX_HI_MSB:0]; |
|
wire [16:0] frame1_ptr_hi_tmp = {{16-`APIX_HI_MSB{1'b0}}, frame1_ptr_hi}; |
wire [15:0] frame1_ptr_hi_rd = frame1_ptr_hi_tmp[15:0]; |
`endif |
`endif |
|
//------------------------------------------------ |
// FRAME1_PTR_LO Register |
//------------------------------------------------ |
`ifdef WITH_FRAME1_POINTER |
reg [`APIX_LO_MSB:0] frame1_ptr_lo; |
|
wire frame1_ptr_lo_wr = reg_wr[FRAME1_PTR_LO]; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) frame1_ptr_lo <= {`APIX_LO_MSB+1{1'b0}}; |
else if (frame1_ptr_lo_wr) frame1_ptr_lo <= per_din_i[`APIX_LO_MSB:0]; |
|
`ifdef VRAM_BIGGER_4_KW |
assign frame1_ptr = {frame1_ptr_hi[`APIX_HI_MSB:0], frame1_ptr_lo}; |
wire [15:0] frame1_ptr_lo_rd = frame1_ptr_lo; |
`else |
assign frame1_ptr = {frame1_ptr_lo[`APIX_LO_MSB:0]}; |
wire [16:0] frame1_ptr_lo_tmp = {{16-`APIX_LO_MSB{1'b0}}, frame1_ptr_lo}; |
wire [15:0] frame1_ptr_lo_rd = frame1_ptr_lo_tmp[15:0]; |
`endif |
`endif |
|
//------------------------------------------------ |
// FRAME2_PTR_HI Register |
//------------------------------------------------ |
`ifdef WITH_FRAME2_POINTER |
`ifdef VRAM_BIGGER_4_KW |
reg [`APIX_HI_MSB:0] frame2_ptr_hi; |
|
wire frame2_ptr_hi_wr = reg_wr[FRAME2_PTR_HI]; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) frame2_ptr_hi <= {`APIX_HI_MSB+1{1'b0}}; |
else if (frame2_ptr_hi_wr) frame2_ptr_hi <= per_din_i[`APIX_HI_MSB:0]; |
|
wire [16:0] frame2_ptr_hi_tmp = {{16-`APIX_HI_MSB{1'b0}}, frame2_ptr_hi}; |
wire [15:0] frame2_ptr_hi_rd = frame2_ptr_hi_tmp[15:0]; |
`endif |
`endif |
|
//------------------------------------------------ |
// FRAME2_PTR_LO Register |
//------------------------------------------------ |
`ifdef WITH_FRAME2_POINTER |
reg [`APIX_LO_MSB:0] frame2_ptr_lo; |
|
wire frame2_ptr_lo_wr = reg_wr[FRAME2_PTR_LO]; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) frame2_ptr_lo <= {`APIX_LO_MSB+1{1'b0}}; |
else if (frame2_ptr_lo_wr) frame2_ptr_lo <= per_din_i[`APIX_LO_MSB:0]; |
|
`ifdef VRAM_BIGGER_4_KW |
assign frame2_ptr = {frame2_ptr_hi[`APIX_HI_MSB:0], frame2_ptr_lo}; |
wire [15:0] frame2_ptr_lo_rd = frame2_ptr_lo; |
`else |
assign frame2_ptr = {frame2_ptr_lo[`APIX_LO_MSB:0]}; |
wire [16:0] frame2_ptr_lo_tmp = {{16-`APIX_LO_MSB{1'b0}}, frame2_ptr_lo}; |
wire [15:0] frame2_ptr_lo_rd = frame2_ptr_lo_tmp[15:0]; |
`endif |
`endif |
|
//------------------------------------------------ |
// FRAME3_PTR_HI Register |
//------------------------------------------------ |
`ifdef WITH_FRAME3_POINTER |
`ifdef VRAM_BIGGER_4_KW |
reg [`APIX_HI_MSB:0] frame3_ptr_hi; |
|
wire frame3_ptr_hi_wr = reg_wr[FRAME3_PTR_HI]; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) frame3_ptr_hi <= {`APIX_HI_MSB+1{1'b0}}; |
else if (frame3_ptr_hi_wr) frame3_ptr_hi <= per_din_i[`APIX_HI_MSB:0]; |
|
wire [16:0] frame3_ptr_hi_tmp = {{16-`APIX_HI_MSB{1'b0}},frame3_ptr_hi}; |
wire [15:0] frame3_ptr_hi_rd = frame3_ptr_hi_tmp[15:0]; |
`endif |
`endif |
|
//------------------------------------------------ |
// FRAME3_PTR_LO Register |
//------------------------------------------------ |
`ifdef WITH_FRAME3_POINTER |
reg [`APIX_LO_MSB:0] frame3_ptr_lo; |
|
wire frame3_ptr_lo_wr = reg_wr[FRAME3_PTR_LO]; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) frame3_ptr_lo <= {`APIX_LO_MSB+1{1'b0}}; |
else if (frame3_ptr_lo_wr) frame3_ptr_lo <= per_din_i[`APIX_LO_MSB:0]; |
|
`ifdef VRAM_BIGGER_4_KW |
assign frame3_ptr = {frame3_ptr_hi[`APIX_HI_MSB:0], frame3_ptr_lo}; |
wire [15:0] frame3_ptr_lo_rd = frame3_ptr_lo; |
`else |
assign frame3_ptr = {frame3_ptr_lo[`APIX_LO_MSB:0]}; |
wire [16:0] frame3_ptr_lo_tmp = {{16-`APIX_LO_MSB{1'b0}}, frame3_ptr_lo}; |
wire [15:0] frame3_ptr_lo_rd = frame3_ptr_lo_tmp[15:0]; |
`endif |
`endif |
|
//------------------------------------------------ |
// VID_RAM0 Interface |
//------------------------------------------------ |
wire [15:0] vid_ram0_cfg; |
wire [15:0] vid_ram0_width; |
`ifdef VRAM_BIGGER_4_KW |
wire [15:0] vid_ram0_addr_hi; |
`endif |
wire [15:0] vid_ram0_addr_lo; |
wire [15:0] vid_ram0_data; |
|
wire vid_ram0_we; |
wire vid_ram0_ce; |
wire [15:0] vid_ram0_din; |
wire [`APIX_MSB:0] vid_ram0_addr_nxt; |
wire vid_ram0_access; |
|
ogfx_reg_vram_if ogfx_reg_vram0_if_inst ( |
|
// OUTPUTs |
.vid_ram_cfg_o ( vid_ram0_cfg ), // VID_RAM0_CFG Register |
.vid_ram_width_o ( vid_ram0_width ), // VID_RAM0_WIDTH Register |
`ifdef VRAM_BIGGER_4_KW |
.vid_ram_addr_hi_o ( vid_ram0_addr_hi ), // VID_RAM0_ADDR_HI Register |
`endif |
.vid_ram_addr_lo_o ( vid_ram0_addr_lo ), // VID_RAM0_ADDR_LO Register |
.vid_ram_data_o ( vid_ram0_data ), // VID_RAM0_DATA Register |
|
.vid_ram_we_o ( vid_ram0_we ), // Video-RAM Write strobe |
.vid_ram_ce_o ( vid_ram0_ce ), // Video-RAM Chip enable |
.vid_ram_din_o ( vid_ram0_din ), // Video-RAM Data input |
.vid_ram_addr_nxt_o ( vid_ram0_addr_nxt ), // Video-RAM Next address |
.vid_ram_access_o ( vid_ram0_access ), // Video-RAM Access |
|
// INPUTs |
.mclk ( mclk ), // Main system clock |
.puc_rst ( puc_rst ), // Main system reset |
|
.vid_ram_cfg_wr_i ( reg_wr[VID_RAM0_CFG] ), // VID_RAM0_CFG Write strobe |
.vid_ram_width_wr_i ( reg_wr[VID_RAM0_WIDTH] ), // VID_RAM0_WIDTH Write strobe |
`ifdef VRAM_BIGGER_4_KW |
.vid_ram_addr_hi_wr_i ( reg_wr[VID_RAM0_ADDR_HI] ), // VID_RAM0_ADDR_HI Write strobe |
`endif |
.vid_ram_addr_lo_wr_i ( reg_wr[VID_RAM0_ADDR_LO] ), // VID_RAM0_ADDR_LO Write strobe |
.vid_ram_data_wr_i ( reg_wr[VID_RAM0_DATA] ), // VID_RAM0_DATA Write strobe |
.vid_ram_data_rd_i ( reg_rd[VID_RAM0_DATA] ), // VID_RAM0_DATA Read strobe |
|
.dbg_freeze_i ( dbg_freeze_i ), // Freeze auto-increment on read when CPU stopped |
.display_width_i ( display_width_o ), // Display width |
.gfx_mode_1_bpp_i ( gfx_mode_1_bpp ), // Graphic mode 1 bpp resolution |
.gfx_mode_2_bpp_i ( gfx_mode_2_bpp ), // Graphic mode 2 bpp resolution |
.gfx_mode_4_bpp_i ( gfx_mode_4_bpp ), // Graphic mode 4 bpp resolution |
.gfx_mode_8_bpp_i ( gfx_mode_8_bpp ), // Graphic mode 8 bpp resolution |
.gfx_mode_16_bpp_i ( gfx_mode_16_bpp ), // Graphic mode 16 bpp resolution |
|
.per_din_i ( per_din_i ), // Peripheral data input |
.vid_ram_base_addr_i ( vid_ram0_base_addr ), // Video-RAM base address |
.vid_ram_dout_i ( vid_ram_dout_i ) // Video-RAM data input |
); |
|
//------------------------------------------------ |
// VID_RAM1 Interface |
//------------------------------------------------ |
wire [15:0] vid_ram1_cfg; |
wire [15:0] vid_ram1_width; |
`ifdef VRAM_BIGGER_4_KW |
wire [15:0] vid_ram1_addr_hi; |
`endif |
wire [15:0] vid_ram1_addr_lo; |
wire [15:0] vid_ram1_data; |
|
wire vid_ram1_we; |
wire vid_ram1_ce; |
wire [15:0] vid_ram1_din; |
wire [`APIX_MSB:0] vid_ram1_addr_nxt; |
wire vid_ram1_access; |
|
ogfx_reg_vram_if ogfx_reg_vram1_if_inst ( |
|
// OUTPUTs |
.vid_ram_cfg_o ( vid_ram1_cfg ), // VID_RAM1_CFG Register |
.vid_ram_width_o ( vid_ram1_width ), // VID_RAM1_WIDTH Register |
`ifdef VRAM_BIGGER_4_KW |
.vid_ram_addr_hi_o ( vid_ram1_addr_hi ), // VID_RAM1_ADDR_HI Register |
`endif |
.vid_ram_addr_lo_o ( vid_ram1_addr_lo ), // VID_RAM1_ADDR_LO Register |
.vid_ram_data_o ( vid_ram1_data ), // VID_RAM1_DATA Register |
|
.vid_ram_we_o ( vid_ram1_we ), // Video-RAM Write strobe |
.vid_ram_ce_o ( vid_ram1_ce ), // Video-RAM Chip enable |
.vid_ram_din_o ( vid_ram1_din ), // Video-RAM Data input |
.vid_ram_addr_nxt_o ( vid_ram1_addr_nxt ), // Video-RAM Next address |
.vid_ram_access_o ( vid_ram1_access ), // Video-RAM Access |
|
// INPUTs |
.mclk ( mclk ), // Main system clock |
.puc_rst ( puc_rst ), // Main system reset |
|
.vid_ram_cfg_wr_i ( reg_wr[VID_RAM1_CFG] ), // VID_RAM1_CFG Write strobe |
.vid_ram_width_wr_i ( reg_wr[VID_RAM1_WIDTH] ), // VID_RAM1_WIDTH Write strobe |
`ifdef VRAM_BIGGER_4_KW |
.vid_ram_addr_hi_wr_i ( reg_wr[VID_RAM1_ADDR_HI] ), // VID_RAM1_ADDR_HI Write strobe |
`endif |
.vid_ram_addr_lo_wr_i ( reg_wr[VID_RAM1_ADDR_LO] ), // VID_RAM1_ADDR_LO Write strobe |
.vid_ram_data_wr_i ( reg_wr[VID_RAM1_DATA] ), // VID_RAM1_DATA Write strobe |
.vid_ram_data_rd_i ( reg_rd[VID_RAM1_DATA] ), // VID_RAM1_DATA Read strobe |
|
.dbg_freeze_i ( dbg_freeze_i ), // Freeze auto-increment on read when CPU stopped |
.display_width_i ( display_width_o ), // Display width |
.gfx_mode_1_bpp_i ( gfx_mode_1_bpp ), // Graphic mode 1 bpp resolution |
.gfx_mode_2_bpp_i ( gfx_mode_2_bpp ), // Graphic mode 2 bpp resolution |
.gfx_mode_4_bpp_i ( gfx_mode_4_bpp ), // Graphic mode 4 bpp resolution |
.gfx_mode_8_bpp_i ( gfx_mode_8_bpp ), // Graphic mode 8 bpp resolution |
.gfx_mode_16_bpp_i ( gfx_mode_16_bpp ), // Graphic mode 16 bpp resolution |
|
.per_din_i ( per_din_i ), // Peripheral data input |
.vid_ram_base_addr_i ( vid_ram1_base_addr ), // Video-RAM base address |
.vid_ram_dout_i ( vid_ram_dout_i ) // Video-RAM data input |
); |
|
//------------------------------------------------ |
// GPU Interface (GPU_CMD/GPU_STAT) Registers |
//------------------------------------------------ |
|
wire [3:0] gpu_stat_fifo_cnt; |
wire gpu_stat_fifo_empty; |
wire gpu_stat_fifo_full; |
|
ogfx_reg_fifo ogfx_reg_fifo_gpu_inst ( |
|
// OUTPUTs |
.fifo_cnt_o ( gpu_stat_fifo_cnt ), // Fifo counter |
.fifo_data_o ( gpu_data_o ), // Read data output |
.fifo_done_evt_o ( gpu_fifo_done_evt ), // Fifo has been emptied |
.fifo_empty_o ( gpu_stat_fifo_empty ), // Fifo is currentely empty |
.fifo_full_o ( gpu_stat_fifo_full ), // Fifo is currentely full |
.fifo_ovfl_evt_o ( gpu_fifo_ovfl_evt ), // Fifo overflow event |
|
// INPUTs |
.mclk ( mclk ), // Main system clock |
.puc_rst ( puc_rst ), // Main system reset |
|
.fifo_data_i ( per_din_i ), // Read data input |
.fifo_enable_i ( gpu_enable_o ), // Enable fifo (flushed when disabled) |
.fifo_pop_i ( gpu_get_data_i ), // Pop data from the fifo |
.fifo_push_i ( reg_wr[GPU_CMD] ) // Push new data to the fifo |
); |
|
assign gpu_data_avail_o = ~gpu_stat_fifo_empty; |
|
wire [15:0] gpu_stat = {10'h000, gpu_stat_fifo_full, gpu_stat_fifo_empty, gpu_stat_fifo_cnt}; |
|
|
//============================================================================ |
// 4) DATA OUTPUT GENERATION |
//============================================================================ |
|
// Data output mux |
wire [15:0] gfx_ctrl_read = gfx_ctrl & {16{reg_rd[GFX_CTRL ]}}; |
wire [15:0] gfx_status_read = gfx_status & {16{reg_rd[GFX_STATUS ]}}; |
wire [15:0] gfx_irq_read = gfx_irq & {16{reg_rd[GFX_IRQ ]}}; |
|
wire [15:0] display_width_read = display_width_rd & {16{reg_rd[DISPLAY_WIDTH ]}}; |
wire [15:0] display_height_read = display_height_rd & {16{reg_rd[DISPLAY_HEIGHT ]}}; |
`ifdef WITH_DISPLAY_SIZE_HI |
wire [15:0] display_size_hi_read = display_size_hi_rd & {16{reg_rd[DISPLAY_SIZE_HI ]}}; |
`endif |
wire [15:0] display_size_lo_read = display_size_lo_rd & {16{reg_rd[DISPLAY_SIZE_LO ]}}; |
wire [15:0] display_cfg_read = display_cfg & {16{reg_rd[DISPLAY_CFG ]}}; |
|
wire [15:0] lt24_cfg_read = lt24_cfg & {16{reg_rd[LT24_CFG ]}}; |
wire [15:0] lt24_refresh_read = lt24_refresh & {16{reg_rd[LT24_REFRESH ]}}; |
wire [15:0] lt24_refresh_sync_read = lt24_refresh_sync & {16{reg_rd[LT24_REFRESH_SYNC ]}}; |
wire [15:0] lt24_cmd_read = lt24_cmd & {16{reg_rd[LT24_CMD ]}}; |
wire [15:0] lt24_cmd_param_read = lt24_cmd_param_o & {16{reg_rd[LT24_CMD_PARAM ]}}; |
wire [15:0] lt24_cmd_dfill_read = lt24_cmd_dfill_o & {16{reg_rd[LT24_CMD_DFILL ]}}; |
wire [15:0] lt24_status_read = lt24_status & {16{reg_rd[LT24_STATUS ]}}; |
|
wire [15:0] lut_ram_addr_read = lut_ram_addr_rd & {16{reg_rd[LUT_RAM_ADDR ]}}; |
wire [15:0] lut_ram_data_read = lut_ram_data & {16{reg_rd[LUT_RAM_DATA ]}}; |
|
wire [15:0] frame_select_read = frame_select & {16{reg_rd[FRAME_SELECT ]}}; |
`ifdef VRAM_BIGGER_4_KW |
wire [15:0] frame0_ptr_hi_read = frame0_ptr_hi_rd & {16{reg_rd[FRAME0_PTR_HI ]}}; |
`endif |
wire [15:0] frame0_ptr_lo_read = frame0_ptr_lo_rd & {16{reg_rd[FRAME0_PTR_LO ]}}; |
`ifdef WITH_FRAME1_POINTER |
`ifdef VRAM_BIGGER_4_KW |
wire [15:0] frame1_ptr_hi_read = frame1_ptr_hi_rd & {16{reg_rd[FRAME1_PTR_HI ]}}; |
`endif |
wire [15:0] frame1_ptr_lo_read = frame1_ptr_lo_rd & {16{reg_rd[FRAME1_PTR_LO ]}}; |
`endif |
`ifdef WITH_FRAME2_POINTER |
`ifdef VRAM_BIGGER_4_KW |
wire [15:0] frame2_ptr_hi_read = frame2_ptr_hi_rd & {16{reg_rd[FRAME2_PTR_HI ]}}; |
`endif |
wire [15:0] frame2_ptr_lo_read = frame2_ptr_lo_rd & {16{reg_rd[FRAME2_PTR_LO ]}}; |
`endif |
`ifdef WITH_FRAME3_POINTER |
`ifdef VRAM_BIGGER_4_KW |
wire [15:0] frame3_ptr_hi_read = frame3_ptr_hi_rd & {16{reg_rd[FRAME3_PTR_HI ]}}; |
`endif |
wire [15:0] frame3_ptr_lo_read = frame3_ptr_lo_rd & {16{reg_rd[FRAME3_PTR_LO ]}}; |
`endif |
wire [15:0] vid_ram0_cfg_read = vid_ram0_cfg & {16{reg_rd[VID_RAM0_CFG ]}}; |
wire [15:0] vid_ram0_width_read = vid_ram0_width & {16{reg_rd[VID_RAM0_WIDTH ]}}; |
`ifdef VRAM_BIGGER_4_KW |
wire [15:0] vid_ram0_addr_hi_read = vid_ram0_addr_hi & {16{reg_rd[VID_RAM0_ADDR_HI ]}}; |
`endif |
wire [15:0] vid_ram0_addr_lo_read = vid_ram0_addr_lo & {16{reg_rd[VID_RAM0_ADDR_LO ]}}; |
wire [15:0] vid_ram0_data_read = vid_ram0_data & {16{reg_rd[VID_RAM0_DATA ]}}; |
|
wire [15:0] vid_ram1_cfg_read = vid_ram1_cfg & {16{reg_rd[VID_RAM1_CFG ]}}; |
wire [15:0] vid_ram1_width_read = vid_ram1_width & {16{reg_rd[VID_RAM1_WIDTH ]}}; |
`ifdef VRAM_BIGGER_4_KW |
wire [15:0] vid_ram1_addr_hi_read = vid_ram1_addr_hi & {16{reg_rd[VID_RAM1_ADDR_HI ]}}; |
`endif |
wire [15:0] vid_ram1_addr_lo_read = vid_ram1_addr_lo & {16{reg_rd[VID_RAM1_ADDR_LO ]}}; |
wire [15:0] vid_ram1_data_read = vid_ram1_data & {16{reg_rd[VID_RAM1_DATA ]}}; |
wire [15:0] gpu_cmd_read = 16'h0000 & {16{reg_rd[GPU_CMD ]}}; |
wire [15:0] gpu_stat_read = gpu_stat & {16{reg_rd[GPU_STAT ]}}; |
|
|
wire [15:0] per_dout_o = gfx_ctrl_read | |
gfx_status_read | |
gfx_irq_read | |
|
display_width_read | |
display_height_read | |
`ifdef WITH_DISPLAY_SIZE_HI |
display_size_hi_read | |
`endif |
display_size_lo_read | |
display_cfg_read | |
|
lt24_cfg_read | |
lt24_refresh_read | |
lt24_refresh_sync_read | |
lt24_cmd_read | |
lt24_cmd_param_read | |
lt24_cmd_dfill_read | |
lt24_status_read | |
|
lut_ram_addr_read | |
lut_ram_data_read | |
|
frame_select_read | |
`ifdef VRAM_BIGGER_4_KW |
frame0_ptr_hi_read | |
`endif |
frame0_ptr_lo_read | |
`ifdef WITH_FRAME1_POINTER |
`ifdef VRAM_BIGGER_4_KW |
frame1_ptr_hi_read | |
`endif |
frame1_ptr_lo_read | |
`endif |
`ifdef WITH_FRAME2_POINTER |
`ifdef VRAM_BIGGER_4_KW |
frame2_ptr_hi_read | |
`endif |
frame2_ptr_lo_read | |
`endif |
`ifdef WITH_FRAME3_POINTER |
`ifdef VRAM_BIGGER_4_KW |
frame3_ptr_hi_read | |
`endif |
frame3_ptr_lo_read | |
`endif |
vid_ram0_cfg_read | |
vid_ram0_width_read | |
`ifdef VRAM_BIGGER_4_KW |
vid_ram0_addr_hi_read | |
`endif |
vid_ram0_addr_lo_read | |
vid_ram0_data_read | |
|
vid_ram1_cfg_read | |
vid_ram1_width_read | |
`ifdef VRAM_BIGGER_4_KW |
vid_ram1_addr_hi_read | |
`endif |
vid_ram1_addr_lo_read | |
vid_ram1_data_read | |
gpu_cmd_read | |
gpu_stat_read; |
|
|
//============================================================================ |
// 5) VIDEO MEMORY INTERFACE |
//============================================================================ |
|
// Write access strobe |
assign vid_ram_wen_o = ~(vid_ram0_we | vid_ram1_we); |
|
// Chip enable. |
assign vid_ram_cen_o = ~(vid_ram0_ce | vid_ram1_ce); |
|
// Data to be written |
assign vid_ram_din_o = (vid_ram0_din | vid_ram1_din); |
|
// Detect memory accesses for ADDR update |
wire vid_ram_access = (vid_ram0_access | vid_ram1_access); |
|
// Next Address |
wire [`APIX_MSB:0] vid_ram_addr_nxt = (vid_ram0_addr_nxt | vid_ram1_addr_nxt); |
|
// Align according to graphic mode |
wire [`VRAM_MSB:0] vid_ram_addr_align = ({`VRAM_AWIDTH{gfx_mode_1_bpp }} & vid_ram_addr_nxt[`APIX_MSB-0:4]) | |
({`VRAM_AWIDTH{gfx_mode_2_bpp }} & vid_ram_addr_nxt[`APIX_MSB-1:3]) | |
({`VRAM_AWIDTH{gfx_mode_4_bpp }} & vid_ram_addr_nxt[`APIX_MSB-2:2]) | |
({`VRAM_AWIDTH{gfx_mode_8_bpp }} & vid_ram_addr_nxt[`APIX_MSB-3:1]) | |
({`VRAM_AWIDTH{gfx_mode_16_bpp}} & vid_ram_addr_nxt[`APIX_MSB-4:0]) ; |
|
// Generate Video RAM address |
reg [`VRAM_MSB:0] vid_ram_addr_o; |
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) vid_ram_addr_o <= {`VRAM_AWIDTH{1'b0}}; |
else if (vid_ram_access) vid_ram_addr_o <= vid_ram_addr_align; |
|
|
endmodule // ogfx_reg |
|
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_undefines.v" |
`endif |
/trunk/core/rtl/verilog/ogfx_backend_lut_fifo.v
0,0 → 1,363
//---------------------------------------------------------------------------- |
// 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_backend_lut_fifo.v |
// |
// *Module Description: |
// Mini-cache memory for the LUT memory accesses. |
// |
// *Author(s): |
// - Olivier Girard, olgirard@gmail.com |
// |
//---------------------------------------------------------------------------- |
// $Rev$ |
// $LastChangedBy$ |
// $LastChangedDate$ |
//---------------------------------------------------------------------------- |
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_defines.v" |
`endif |
|
module ogfx_backend_lut_fifo ( |
|
// OUTPUTs |
frame_data_request_o, // Request for next frame data |
|
refresh_data_o, // Display Refresh data |
refresh_data_ready_o, // Display Refresh data ready |
|
`ifdef WITH_PROGRAMMABLE_LUT |
lut_ram_addr_o, // LUT-RAM address |
lut_ram_cen_o, // LUT-RAM enable (active low) |
`endif |
|
// INPUTs |
mclk, // Main system clock |
puc_rst, // Main system reset |
|
frame_data_i, // Frame data |
frame_data_ready_i, // Frame data ready |
|
gfx_mode_i, // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp) |
|
`ifdef WITH_PROGRAMMABLE_LUT |
lut_ram_dout_i, // LUT-RAM data output |
lut_ram_dout_rdy_nxt_i, // LUT-RAM data output ready during next cycle |
`endif |
|
refresh_active_i, // Display refresh on going |
refresh_data_request_i, // Request for next refresh data |
refresh_lut_select_i // Refresh LUT bank selection |
); |
|
// OUTPUTs |
//========= |
output frame_data_request_o; // Request for next frame data |
|
output [15:0] refresh_data_o; // Display Refresh data |
output refresh_data_ready_o; // Display Refresh data ready |
|
`ifdef WITH_PROGRAMMABLE_LUT |
output [`LRAM_MSB:0] lut_ram_addr_o; // LUT-RAM address |
output lut_ram_cen_o; // LUT-RAM enable (active low) |
`endif |
|
// INPUTs |
//========= |
input mclk; // Main system clock |
input puc_rst; // Main system reset |
|
input [15:0] frame_data_i; // Frame data |
input frame_data_ready_i; // Frame data ready |
|
input [2:0] gfx_mode_i; // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp) |
|
`ifdef WITH_PROGRAMMABLE_LUT |
input [15:0] lut_ram_dout_i; // LUT-RAM data output |
input lut_ram_dout_rdy_nxt_i; // LUT-RAM data output ready during next cycle |
`endif |
|
input refresh_active_i; // Display refresh on going |
input refresh_data_request_i; // Request for next refresh data |
input [1:0] refresh_lut_select_i; // Refresh LUT bank selection |
|
|
//============================================================================= |
// 1) WIRE, REGISTERS AND PARAMETER DECLARATION |
//============================================================================= |
|
// State machine registers |
reg [1:0] lut_state; |
reg [1:0] lut_state_nxt; |
|
// State definition |
parameter STATE_IDLE = 0, |
STATE_FRAME_DATA = 1, |
STATE_LUT_DATA = 2, |
STATE_HOLD = 3; |
|
// Some parameter(s) |
parameter FIFO_EMPTY = 3'h0, |
FIFO_FULL = 3'h5; |
|
// Video modes decoding |
wire gfx_mode_1_bpp = (gfx_mode_i == 3'b000); |
wire gfx_mode_2_bpp = (gfx_mode_i == 3'b001); |
wire gfx_mode_4_bpp = (gfx_mode_i == 3'b010); |
wire gfx_mode_8_bpp = (gfx_mode_i == 3'b011); |
wire gfx_mode_16_bpp = ~(gfx_mode_8_bpp | gfx_mode_4_bpp | |
gfx_mode_2_bpp | gfx_mode_1_bpp); |
|
// Others |
reg [2:0] fifo_counter; |
wire [2:0] fifo_counter_nxt; |
|
|
//============================================================================ |
// 2) HARD CODED LOOKUP TABLE |
//============================================================================ |
|
wire [15:0] lut_hw_data_1_bpp = ({5'b00000, 6'b000000, 5'b00000} & {16{frame_data_i[0] ==1'b0 }}) | // 1 bpp: Black |
({5'b11111, 6'b111111, 5'b11111} & {16{frame_data_i[0] ==1'b1 }}) ; // White |
|
wire [15:0] lut_hw_data_2_bpp = ({5'b00000, 6'b000000, 5'b00000} & {16{frame_data_i[0] ==2'b00 }}) | // 2 bpp: Black |
({5'b01000, 6'b010000, 5'b01000} & {16{frame_data_i[0] ==2'b01 }}) | // Dark Gray |
({5'b11000, 6'b110000, 5'b11000} & {16{frame_data_i[0] ==2'b10 }}) | // Light Gray |
({5'b11111, 6'b111111, 5'b11111} & {16{frame_data_i[0] ==2'b11 }}) ; // White |
|
wire [15:0] lut_hw_data_4_bpp = ({5'b00000, 6'b000000, 5'b00000} & {16{frame_data_i[3:0]==4'b0000}}) | // 4 bpp: Black |
({5'b00000, 6'b000000, 5'b10000} & {16{frame_data_i[3:0]==4'b0001}}) | // Dark Blue |
({5'b10000, 6'b000000, 5'b00000} & {16{frame_data_i[3:0]==4'b0010}}) | // Dark Red |
({5'b10000, 6'b000000, 5'b10000} & {16{frame_data_i[3:0]==4'b0011}}) | // Dark Magenta |
({5'b00000, 6'b100000, 5'b00000} & {16{frame_data_i[3:0]==4'b0100}}) | // Dark Green |
({5'b00000, 6'b100000, 5'b10000} & {16{frame_data_i[3:0]==4'b0101}}) | // Dark Cyan |
({5'b10000, 6'b100000, 5'b00000} & {16{frame_data_i[3:0]==4'b0110}}) | // Dark Yellow |
({5'b10000, 6'b100000, 5'b10000} & {16{frame_data_i[3:0]==4'b0111}}) | // Gray |
({5'b00000, 6'b000000, 5'b00000} & {16{frame_data_i[3:0]==4'b1000}}) | // Black |
({5'b00000, 6'b000000, 5'b11111} & {16{frame_data_i[3:0]==4'b1001}}) | // Blue |
({5'b11111, 6'b000000, 5'b00000} & {16{frame_data_i[3:0]==4'b1010}}) | // Red |
({5'b11111, 6'b000000, 5'b11111} & {16{frame_data_i[3:0]==4'b1011}}) | // Magenta |
({5'b00000, 6'b111111, 5'b00000} & {16{frame_data_i[3:0]==4'b1100}}) | // Green |
({5'b00000, 6'b111111, 5'b11111} & {16{frame_data_i[3:0]==4'b1101}}) | // Cyan |
({5'b11111, 6'b111111, 5'b00000} & {16{frame_data_i[3:0]==4'b1110}}) | // Yellow |
({5'b11111, 6'b111111, 5'b11111} & {16{frame_data_i[3:0]==4'b1111}}); // White |
|
wire [15:0] lut_hw_data_8_bpp = {frame_data_i[7],frame_data_i[6],frame_data_i[5],frame_data_i[5],frame_data_i[5], // 8 bpp: R = D<7,6,5,5,5> |
frame_data_i[4],frame_data_i[3],frame_data_i[2],frame_data_i[2],frame_data_i[2],frame_data_i[2], // G = D<4,3,2,2,2,2> |
frame_data_i[1],frame_data_i[0],frame_data_i[0],frame_data_i[0],frame_data_i[0]}; // B = D<1,0,0,0,0> |
|
wire [15:0] lut_hw_data = (lut_hw_data_1_bpp & {16{gfx_mode_1_bpp}}) | |
(lut_hw_data_2_bpp & {16{gfx_mode_2_bpp}}) | |
(lut_hw_data_4_bpp & {16{gfx_mode_4_bpp}}) | |
(lut_hw_data_8_bpp & {16{gfx_mode_8_bpp}}); |
|
wire lut_hw_enabled = ~gfx_mode_16_bpp & ~refresh_lut_select_i[0]; |
wire lut_sw_enabled = ~gfx_mode_16_bpp & refresh_lut_select_i[0]; |
|
|
//============================================================================ |
// 3) STATE MACHINE |
//============================================================================ |
|
//-------------------------------- |
// States Transitions |
//-------------------------------- |
always @(lut_state or refresh_active_i or frame_data_ready_i or |
`ifdef WITH_PROGRAMMABLE_LUT |
lut_sw_enabled or lut_ram_dout_rdy_nxt_i or |
`endif |
fifo_counter_nxt) |
case(lut_state) |
|
STATE_IDLE : lut_state_nxt = ~refresh_active_i ? STATE_IDLE : STATE_FRAME_DATA ; |
|
STATE_FRAME_DATA : lut_state_nxt = ~refresh_active_i ? STATE_IDLE : |
~frame_data_ready_i ? STATE_FRAME_DATA : |
`ifdef WITH_PROGRAMMABLE_LUT |
lut_sw_enabled ? STATE_LUT_DATA : |
`endif |
STATE_HOLD ; |
|
`ifdef WITH_PROGRAMMABLE_LUT |
STATE_LUT_DATA : lut_state_nxt = ~refresh_active_i ? STATE_IDLE : |
lut_ram_dout_rdy_nxt_i ? STATE_HOLD : STATE_LUT_DATA ; |
`endif |
|
STATE_HOLD : lut_state_nxt = ~refresh_active_i ? STATE_IDLE : |
(fifo_counter_nxt!=FIFO_FULL) ? STATE_FRAME_DATA : STATE_HOLD ; |
|
// pragma coverage off |
default : lut_state_nxt = STATE_IDLE; |
// pragma coverage on |
endcase |
|
//-------------------------------- |
// State machine |
//-------------------------------- |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) lut_state <= STATE_IDLE; |
else lut_state <= lut_state_nxt; |
|
|
// Request for the next frame data |
assign frame_data_request_o = (lut_state == STATE_FRAME_DATA); |
|
|
//============================================================================ |
// 4) LUT MEMORY INTERFACE |
//============================================================================ |
|
//-------------------------------- |
// Enable |
//-------------------------------- |
`ifdef WITH_PROGRAMMABLE_LUT |
assign lut_ram_cen_o = ~(lut_state == STATE_LUT_DATA); |
`endif |
|
//-------------------------------- |
// Address |
//-------------------------------- |
// Mask with chip enable to save power |
|
`ifdef WITH_PROGRAMMABLE_LUT |
`ifdef WITH_EXTRA_LUT_BANK |
// Allow LUT bank switching only when the refresh is not on going |
reg refresh_lut_bank_select_sync; |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) refresh_lut_bank_select_sync <= 1'b0; |
else if (~refresh_active_i) refresh_lut_bank_select_sync <= refresh_lut_select_i[1]; |
|
assign lut_ram_addr_o = {refresh_lut_bank_select_sync, frame_data_i[7:0]} & {9{~lut_ram_cen_o}}; |
`else |
assign lut_ram_addr_o = frame_data_i[7:0] & {8{~lut_ram_cen_o}}; |
`endif |
`endif |
|
//-------------------------------- |
// Data Ready |
//-------------------------------- |
// When filling the FIFO, the data is available on the bus |
// one cycle after the rdy_nxt signal |
reg lut_ram_dout_ready; |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) lut_ram_dout_ready <= 1'b0; |
`ifdef WITH_PROGRAMMABLE_LUT |
else lut_ram_dout_ready <= lut_sw_enabled ? lut_ram_dout_rdy_nxt_i : |
(frame_data_ready_i & (lut_state == STATE_FRAME_DATA)); |
`else |
else lut_ram_dout_ready <= (frame_data_ready_i & (lut_state == STATE_FRAME_DATA)); |
`endif |
|
|
//============================================================================ |
// 5) FIFO COUNTER |
//============================================================================ |
|
// Control signals |
wire fifo_push = lut_ram_dout_ready & (fifo_counter != FIFO_FULL); |
wire fifo_pop = refresh_data_request_i & (fifo_counter != FIFO_EMPTY); |
|
// Fifo counter |
assign fifo_counter_nxt = ~refresh_active_i ? FIFO_EMPTY : // Initialize |
(fifo_push & fifo_pop) ? fifo_counter : // Keep value (pop & push at the same time) |
fifo_push ? fifo_counter + 3'h1 : // Push |
fifo_pop ? fifo_counter - 3'h1 : // Pop |
fifo_counter; // Hold |
|
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) fifo_counter <= FIFO_EMPTY; |
else fifo_counter <= fifo_counter_nxt; |
|
|
//============================================================================ |
// 6) FIFO MEMORY & RD/WR POINTERS |
//============================================================================ |
|
// Write pointer |
reg [2:0] wr_ptr; |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) wr_ptr <= 3'h0; |
else if (~refresh_active_i) wr_ptr <= 3'h0; |
else if (fifo_push) |
begin |
if (wr_ptr==(FIFO_FULL-1)) wr_ptr <= 3'h0; |
else wr_ptr <= wr_ptr + 3'h1; |
end |
|
// Memory |
reg [15:0] fifo_mem [0:4]; |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) |
begin |
fifo_mem[0] <= 16'h0000; |
fifo_mem[1] <= 16'h0000; |
fifo_mem[2] <= 16'h0000; |
fifo_mem[3] <= 16'h0000; |
fifo_mem[4] <= 16'h0000; |
end |
else if (fifo_push) |
begin |
fifo_mem[wr_ptr] <= lut_hw_enabled ? lut_hw_data : |
`ifdef WITH_PROGRAMMABLE_LUT |
lut_sw_enabled ? lut_ram_dout_i : |
`endif |
frame_data_i; |
end |
|
// Read pointer |
reg [2:0] rd_ptr; |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) rd_ptr <= 3'h0; |
else if (~refresh_active_i) rd_ptr <= 3'h0; |
else if (fifo_pop) |
begin |
if (rd_ptr==(FIFO_FULL-1)) rd_ptr <= 3'h0; |
else rd_ptr <= rd_ptr + 3'h1; |
end |
|
//============================================================================ |
// 7) REFRESH_DATA |
//============================================================================ |
|
// Refresh Data is ready |
reg refresh_data_ready_o; |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) refresh_data_ready_o <= 1'h0; |
else if (~refresh_active_i) refresh_data_ready_o <= 1'h0; |
else refresh_data_ready_o <= fifo_pop; |
|
// Refresh Data |
reg [15:0] refresh_data_o; |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) refresh_data_o <= 16'h0000; |
else if (fifo_pop) refresh_data_o <= fifo_mem[rd_ptr]; |
|
|
endmodule // ogfx_backend_lut_fifo |
|
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_undefines.v" |
`endif |
/trunk/core/rtl/verilog/ogfx_reg_vram_if.v
0,0 → 1,446
//---------------------------------------------------------------------------- |
// 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_reg_vram_if.v |
// |
// *Module Description: |
// Video-RAM Registers interface. |
// |
// *Author(s): |
// - Olivier Girard, olgirard@gmail.com |
// |
//---------------------------------------------------------------------------- |
// $Rev$ |
// $LastChangedBy$ |
// $LastChangedDate$ |
//---------------------------------------------------------------------------- |
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_defines.v" |
`endif |
|
module ogfx_reg_vram_if ( |
|
// OUTPUTs |
vid_ram_cfg_o, // VID_RAMx_CFG Register |
vid_ram_width_o, // VID_RAMx_WIDTH Register |
`ifdef VRAM_BIGGER_4_KW |
vid_ram_addr_hi_o, // VID_RAMx_ADDR_HI Register |
`endif |
vid_ram_addr_lo_o, // VID_RAMx_ADDR_LO Register |
vid_ram_data_o, // VID_RAMx_DATA Register |
|
vid_ram_we_o, // Video-RAM Write strobe |
vid_ram_ce_o, // Video-RAM Chip enable |
vid_ram_din_o, // Video-RAM Data input |
vid_ram_addr_nxt_o, // Video-RAM Next address |
vid_ram_access_o, // Video-RAM Access |
|
// INPUTs |
mclk, // Main system clock |
puc_rst, // Main system reset |
|
vid_ram_cfg_wr_i, // VID_RAMx_CFG Write strobe |
vid_ram_width_wr_i, // VID_RAMx_WIDTH Write strobe |
`ifdef VRAM_BIGGER_4_KW |
vid_ram_addr_hi_wr_i, // VID_RAMx_ADDR_HI Write strobe |
`endif |
vid_ram_addr_lo_wr_i, // VID_RAMx_ADDR_LO Write strobe |
vid_ram_data_wr_i, // VID_RAMx_DATA Write strobe |
vid_ram_data_rd_i, // VID_RAMx_DATA Read strobe |
|
dbg_freeze_i, // Freeze auto-increment on read when CPU stopped |
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 |
|
per_din_i, // Peripheral data input |
vid_ram_base_addr_i, // Video-RAM base address |
vid_ram_dout_i // Video-RAM data input |
); |
|
// OUTPUTs |
//========= |
output [15:0] vid_ram_cfg_o; // VID_RAMx_CFG Register |
output [15:0] vid_ram_width_o; // VID_RAMx_WIDTH Register |
`ifdef VRAM_BIGGER_4_KW |
output [15:0] vid_ram_addr_hi_o; // VID_RAMx_ADDR_HI Register |
`endif |
output [15:0] vid_ram_addr_lo_o; // VID_RAMx_ADDR_LO Register |
output [15:0] vid_ram_data_o; // VID_RAMx_DATA Register |
|
output vid_ram_we_o; // Video-RAM Write strobe |
output vid_ram_ce_o; // Video-RAM Chip enable |
output [15:0] vid_ram_din_o; // Video-RAM Data input |
output [`APIX_MSB:0] vid_ram_addr_nxt_o; // Video-RAM Next address |
output vid_ram_access_o; // Video-RAM Access |
|
// INPUTs |
//========= |
input mclk; // Main system clock |
input puc_rst; // Main system reset |
|
input vid_ram_cfg_wr_i; // VID_RAMx_CFG Write strobe |
input vid_ram_width_wr_i; // VID_RAMx_WIDTH Write strobe |
`ifdef VRAM_BIGGER_4_KW |
input vid_ram_addr_hi_wr_i; // VID_RAMx_ADDR_HI Write strobe |
`endif |
input vid_ram_addr_lo_wr_i; // VID_RAMx_ADDR_LO Write strobe |
input vid_ram_data_wr_i; // VID_RAMx_DATA Write strobe |
input vid_ram_data_rd_i; // VID_RAMx_DATA Read strobe |
|
input dbg_freeze_i; // Freeze auto-increment on read when CPU stopped |
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 [15:0] per_din_i; // Peripheral data input |
input [`APIX_MSB:0] vid_ram_base_addr_i; // Video-RAM base address |
input [15:0] vid_ram_dout_i; // Video-RAM data input |
|
|
//============================================================================= |
// 1) WIRE AND FUNCTION DECLARATIONS |
//============================================================================= |
|
// 16 bits one-hot decoder |
function [15:0] one_hot16; |
input [3:0] binary; |
begin |
one_hot16 = 16'h0000; |
one_hot16[binary] = 1'b1; |
end |
endfunction |
|
|
|
//============================================================================ |
// 2) REGISTERS |
//============================================================================ |
|
//------------------------------------------------ |
// VID_RAMx_CFG Register |
//------------------------------------------------ |
reg vid_ram_rmw_mode; |
reg vid_ram_msk_mode; |
reg vid_ram_win_mode; |
reg vid_ram_win_x_swap; |
reg vid_ram_win_y_swap; |
reg vid_ram_win_cl_swap; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) |
begin |
vid_ram_win_cl_swap <= 1'b0; |
vid_ram_win_y_swap <= 1'b0; |
vid_ram_win_x_swap <= 1'b0; |
vid_ram_rmw_mode <= 1'b0; |
vid_ram_msk_mode <= 1'b0; |
vid_ram_win_mode <= 1'b0; |
end |
else if (vid_ram_cfg_wr_i) |
begin |
vid_ram_win_cl_swap <= per_din_i[0]; |
vid_ram_win_y_swap <= per_din_i[1]; |
vid_ram_win_x_swap <= per_din_i[2]; |
vid_ram_rmw_mode <= per_din_i[4]; |
vid_ram_msk_mode <= per_din_i[5]; |
vid_ram_win_mode <= per_din_i[6]; |
end |
|
assign vid_ram_cfg_o = {8'h00, 1'b0, vid_ram_win_mode, vid_ram_msk_mode, vid_ram_rmw_mode , |
1'b0, vid_ram_win_x_swap, vid_ram_win_y_swap, vid_ram_win_cl_swap}; |
|
//------------------------------------------------ |
// VID_RAMx_WIDTH Register |
//------------------------------------------------ |
reg [`LPIX_MSB:0] vid_ram_width; |
|
// width must be at least 1 |
wire [`LPIX_MSB:0] vid_ram_width_nxt = (|per_din_i[`LPIX_MSB:0]) ? per_din_i[`LPIX_MSB:0] : {{`LPIX_MSB{1'b0}}, 1'b1}; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) vid_ram_width <= {{`LPIX_MSB{1'b0}}, 1'b1}; |
else if (vid_ram_width_wr_i) vid_ram_width <= vid_ram_width_nxt; |
|
wire [16:0] vid_ram_width_tmp = {{16-`LPIX_MSB{1'b0}}, vid_ram_width}; |
assign vid_ram_width_o = vid_ram_width_tmp[15:0]; |
|
|
//------------------------------------------------ |
// VID_RAMx_ADDR_HI Register |
//------------------------------------------------ |
wire [`APIX_MSB:0] vid_ram_addr; |
wire [`APIX_MSB:0] vid_ram_addr_inc; |
wire vid_ram_addr_inc_wr; |
|
`ifdef VRAM_BIGGER_4_KW |
reg [`APIX_HI_MSB:0] vid_ram_addr_hi; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) vid_ram_addr_hi <= {`APIX_HI_MSB+1{1'b0}}; |
else if (vid_ram_addr_hi_wr_i) vid_ram_addr_hi <= per_din_i[`APIX_HI_MSB:0]; |
else if (vid_ram_addr_inc_wr) vid_ram_addr_hi <= vid_ram_addr_inc[`APIX_MSB:16]; |
|
wire [16:0] vid_ram_addr_hi_tmp = {{16-`APIX_HI_MSB{1'b0}},vid_ram_addr_hi}; |
assign vid_ram_addr_hi_o = vid_ram_addr_hi_tmp[15:0]; |
`endif |
|
//------------------------------------------------ |
// VID_RAMx_ADDR_LO Register |
//------------------------------------------------ |
reg [`APIX_LO_MSB:0] vid_ram_addr_lo; |
reg vid_ram_addr_lo_wr_dly; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) vid_ram_addr_lo <= {`APIX_LO_MSB+1{1'b0}}; |
else if (vid_ram_addr_lo_wr_i) vid_ram_addr_lo <= per_din_i[`APIX_LO_MSB:0]; |
else if (vid_ram_addr_inc_wr) vid_ram_addr_lo <= vid_ram_addr_inc[`APIX_LO_MSB:0]; |
|
`ifdef VRAM_BIGGER_4_KW |
assign vid_ram_addr = {vid_ram_addr_hi[`APIX_HI_MSB:0], vid_ram_addr_lo}; |
assign vid_ram_addr_lo_o = vid_ram_addr_lo; |
`else |
assign vid_ram_addr = {vid_ram_addr_lo[`APIX_LO_MSB:0]}; |
wire [16:0] vid_ram_addr_lo_tmp = {{16-`APIX_LO_MSB{1'b0}},vid_ram_addr_lo}; |
assign vid_ram_addr_lo_o = vid_ram_addr_lo_tmp[15:0]; |
`endif |
|
// Compute the next address |
ogfx_reg_vram_addr ogfx_reg_vram_addr_inst ( |
|
// OUTPUTs |
.vid_ram_addr_nxt_o ( vid_ram_addr_inc ), // Next Video-RAM address |
|
// INPUTs |
.mclk ( mclk ), // Main system clock |
.puc_rst ( puc_rst ), // Main system reset |
.display_width_i ( display_width_i ), // Display width |
.gfx_mode_1_bpp_i ( gfx_mode_1_bpp_i ), // Graphic mode 1 bpp resolution |
.gfx_mode_2_bpp_i ( gfx_mode_2_bpp_i ), // Graphic mode 2 bpp resolution |
.gfx_mode_4_bpp_i ( gfx_mode_4_bpp_i ), // Graphic mode 4 bpp resolution |
.gfx_mode_8_bpp_i ( gfx_mode_8_bpp_i ), // Graphic mode 8 bpp resolution |
.gfx_mode_16_bpp_i ( gfx_mode_16_bpp_i ), // Graphic mode 16 bpp resolution |
.vid_ram_addr_i ( vid_ram_addr ), // Video-RAM address |
.vid_ram_addr_init_i ( vid_ram_addr_lo_wr_dly ), // Video-RAM address initialization |
.vid_ram_addr_step_i ( vid_ram_addr_inc_wr ), // Video-RAM address step |
.vid_ram_width_i ( vid_ram_width ), // Video-RAM width |
.vid_ram_msk_mode_i ( vid_ram_msk_mode ), // Video-RAM Mask mode enable |
.vid_ram_win_mode_i ( vid_ram_win_mode ), // Video-RAM Windows mode enable |
.vid_ram_win_x_swap_i ( vid_ram_win_x_swap ), // Video-RAM X-Swap configuration |
.vid_ram_win_y_swap_i ( vid_ram_win_y_swap ), // Video-RAM Y-Swap configuration |
.vid_ram_win_cl_swap_i ( vid_ram_win_cl_swap ) // Video-RAM CL-Swap configuration |
); |
|
|
//------------------------------------------------ |
// VID_RAMx_DATA Register |
//------------------------------------------------ |
|
// Format input data for masked mode |
wire [15:0] per_din_mask_mode = (({16{gfx_mode_1_bpp_i & vid_ram_msk_mode }} & {16{per_din_i[0] }}) | |
({16{gfx_mode_2_bpp_i & vid_ram_msk_mode }} & {8{per_din_i[1:0]}}) | |
({16{gfx_mode_4_bpp_i & vid_ram_msk_mode }} & {4{per_din_i[3:0]}}) | |
({16{gfx_mode_8_bpp_i & vid_ram_msk_mode }} & {2{per_din_i[7:0]}}) | |
({16{gfx_mode_16_bpp_i | ~vid_ram_msk_mode }} & per_din_i ) ); |
|
// Prepare data to be written according to mask mode enable |
reg [15:0] vid_ram_data_mask; |
wire [15:0] per_din_ram_nxt = per_din_mask_mode & vid_ram_data_mask; |
|
// VIDEO-RAM data Register |
reg [15:0] vid_ram_data; |
wire [15:0] vid_ram_data_mux; |
wire vid_ram_dout_rdy; |
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) vid_ram_data <= 16'h0000; |
else if (vid_ram_data_wr_i) vid_ram_data <= per_din_ram_nxt | (vid_ram_data_mux & ~vid_ram_data_mask); |
else if (vid_ram_dout_rdy) vid_ram_data <= vid_ram_dout_i; |
|
// Make value available in case of early read |
assign vid_ram_data_mux = vid_ram_dout_rdy ? vid_ram_dout_i : vid_ram_data; |
|
// Format read-path for mask mode |
wire [15:0] vid_ram_data_rd_mask = vid_ram_data_mux & vid_ram_data_mask; |
wire vid_ram_data_rd_mask_1_bpp = (|vid_ram_data_rd_mask); |
wire [1:0] vid_ram_data_rd_mask_2_bpp = {(|{vid_ram_data_rd_mask[15], vid_ram_data_rd_mask[13], vid_ram_data_rd_mask[11], vid_ram_data_rd_mask[9], vid_ram_data_rd_mask[7], vid_ram_data_rd_mask[5], vid_ram_data_rd_mask[3], vid_ram_data_rd_mask[1]}), |
(|{vid_ram_data_rd_mask[14], vid_ram_data_rd_mask[12], vid_ram_data_rd_mask[10], vid_ram_data_rd_mask[8], vid_ram_data_rd_mask[6], vid_ram_data_rd_mask[4], vid_ram_data_rd_mask[2], vid_ram_data_rd_mask[0]})}; |
wire [3:0] vid_ram_data_rd_mask_4_bpp = {(|{vid_ram_data_rd_mask[15], vid_ram_data_rd_mask[11], vid_ram_data_rd_mask[7] , vid_ram_data_rd_mask[3]}), |
(|{vid_ram_data_rd_mask[14], vid_ram_data_rd_mask[10], vid_ram_data_rd_mask[6] , vid_ram_data_rd_mask[2]}), |
(|{vid_ram_data_rd_mask[13], vid_ram_data_rd_mask[9] , vid_ram_data_rd_mask[5] , vid_ram_data_rd_mask[1]}), |
(|{vid_ram_data_rd_mask[12], vid_ram_data_rd_mask[8] , vid_ram_data_rd_mask[4] , vid_ram_data_rd_mask[0]})}; |
wire [7:0] vid_ram_data_rd_mask_8_bpp = {(|{vid_ram_data_rd_mask[15], vid_ram_data_rd_mask[7]}), |
(|{vid_ram_data_rd_mask[14], vid_ram_data_rd_mask[6]}), |
(|{vid_ram_data_rd_mask[13], vid_ram_data_rd_mask[5]}), |
(|{vid_ram_data_rd_mask[12], vid_ram_data_rd_mask[4]}), |
(|{vid_ram_data_rd_mask[11], vid_ram_data_rd_mask[3]}), |
(|{vid_ram_data_rd_mask[10], vid_ram_data_rd_mask[2]}), |
(|{vid_ram_data_rd_mask[9] , vid_ram_data_rd_mask[1]}), |
(|{vid_ram_data_rd_mask[8] , vid_ram_data_rd_mask[0]})}; |
wire [15:0] vid_ram_data_rd_mask_16_bpp = vid_ram_data_rd_mask; |
|
assign vid_ram_data_o = ({16{gfx_mode_1_bpp_i & vid_ram_msk_mode }} & {{15{1'b0}},vid_ram_data_rd_mask_1_bpp}) | |
({16{gfx_mode_2_bpp_i & vid_ram_msk_mode }} & {{14{1'b0}},vid_ram_data_rd_mask_2_bpp}) | |
({16{gfx_mode_4_bpp_i & vid_ram_msk_mode }} & {{12{1'b0}},vid_ram_data_rd_mask_4_bpp}) | |
({16{gfx_mode_8_bpp_i & vid_ram_msk_mode }} & { {8{1'b0}},vid_ram_data_rd_mask_8_bpp}) | |
({16{gfx_mode_16_bpp_i | ~vid_ram_msk_mode }} & vid_ram_data_rd_mask_16_bpp) ; |
|
|
//============================================================================ |
// 3) VIDEO MEMORY INTERFACE |
//============================================================================ |
// |
// Trigger a VIDEO-RAM write access after: |
// - a VID_RAMx_DATA register write access |
// |
// Trigger a VIDEO-RAM read access immediately after: |
// - a VID_RAMx_ADDR_LO register write access |
// - a VID_RAMx_DATA register read access |
// - a VID_RAMx_DATA register write access in MSK mode (for resolutions lower than 16bpp) |
// |
|
//-------------------------------------------------- |
// VID_RAM0: Delay software read and write strobes |
//-------------------------------------------------- |
|
// Strobe writing to VID_RAMx_ADDR_LO register |
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) vid_ram_addr_lo_wr_dly <= 1'b0; |
else vid_ram_addr_lo_wr_dly <= vid_ram_addr_lo_wr_i; |
|
// Strobe reading from VID_RAMx_DATA register |
reg vid_ram_data_rd_dly; |
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) vid_ram_data_rd_dly <= 1'b0; |
else vid_ram_data_rd_dly <= vid_ram_data_rd_i; |
|
// Strobe writing to VID_RAMx_DATA register |
reg vid_ram_data_wr_dly; |
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) vid_ram_data_wr_dly <= 1'b0; |
else vid_ram_data_wr_dly <= vid_ram_data_wr_i; |
|
// Trigger read access after a write in MSK mode |
wire vid_ram_data_rd_msk = ((vid_ram_data_wr_dly | vid_ram_data_rd_dly | vid_ram_addr_lo_wr_i) & vid_ram_msk_mode & ~gfx_mode_16_bpp_i); |
|
|
//------------------------------------------------ |
// Compute VIDEO-RAM Strobes & Data |
//------------------------------------------------ |
|
// Write access strobe |
// - one cycle after a VID_RAM_DATA register write access |
assign vid_ram_we_o = vid_ram_data_wr_dly; |
|
// Chip enable. |
// Note: we perform a data read access: |
// - one cycle after a VID_RAM_DATA register read access (so that the address has been incremented) |
// - one cycle after a VID_RAM_ADDR_LO register write |
wire vid_ram_ce_early = (vid_ram_addr_lo_wr_i | vid_ram_data_rd_dly | vid_ram_data_rd_msk | // Read access |
vid_ram_data_wr_i); // Write access |
|
reg [1:0] vid_ram_ce; |
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) vid_ram_ce <= 2'b00; |
else vid_ram_ce <= {vid_ram_ce[0] & ~vid_ram_data_wr_dly, vid_ram_ce_early}; |
|
assign vid_ram_ce_o = vid_ram_ce[0]; |
|
// Data to be written |
assign vid_ram_din_o = {16{vid_ram_ce[0]}} & vid_ram_data; |
|
// Update the VRAM_DATA register one cycle after each memory access |
assign vid_ram_dout_rdy = vid_ram_ce[1]; |
|
|
//------------------------------------------------ |
// Compute VIDEO-RAM Address |
//------------------------------------------------ |
|
// Mux ram address for early read access when ADDR_LO is updated |
`ifdef VRAM_BIGGER_4_KW |
wire [`APIX_MSB:0] vid_ram_addr_mux = vid_ram_addr_lo_wr_i ? {vid_ram_addr[`APIX_MSB:16], per_din_i} : |
vid_ram_data_rd_msk ? vid_ram_addr_inc : vid_ram_addr; |
`else |
wire [`APIX_MSB:0] vid_ram_addr_mux = vid_ram_addr_lo_wr_i ? {per_din_i[`APIX_LO_MSB:0]} : |
vid_ram_data_rd_msk ? vid_ram_addr_inc : vid_ram_addr; |
`endif |
|
// Add frame pointer offset |
wire [`APIX_MSB:0] vid_ram_addr_offset = vid_ram_base_addr_i + vid_ram_addr_mux; |
|
// Detect memory accesses for ADDR update |
wire vid_ram_access_o = vid_ram_data_wr_i | vid_ram_data_rd_dly | vid_ram_addr_lo_wr_i | vid_ram_data_rd_msk; |
|
// Mux Address between the two interfaces |
wire [`APIX_MSB:0] vid_ram_addr_nxt_o = {`APIX_MSB+1{vid_ram_access_o}} & vid_ram_addr_offset; |
|
// Increment the address when accessing the VID_RAMx_DATA register: |
// - one clock cycle after a write access |
// - with the read access (if not in read-modify-write mode) |
assign vid_ram_addr_inc_wr = vid_ram_addr_lo_wr_dly | vid_ram_data_wr_dly | (vid_ram_data_rd_i & ~dbg_freeze_i & ~vid_ram_rmw_mode); |
|
// Compute mask for the address LSBs depending on BPP resolution |
wire [3:0] gfx_mode_addr_msk = ( {4{gfx_mode_1_bpp_i}} | // Take 4 address LSBs in 1bpp mode |
{1'b0, {3{gfx_mode_2_bpp_i}}} | // Take 3 address LSBs in 2bpp mode |
{2'b00, {2{gfx_mode_4_bpp_i}}} | // Take 2 address LSBs in 4bpp mode |
{3'b000, gfx_mode_8_bpp_i}); // Take 1 address LSB in 8bpp mode |
// Take no address LSB in 16bpp mode |
// Generate Data-Mask for the mask mode (Bank 0) |
wire [15:0] vid_ram_data_mask_shift = one_hot16(vid_ram_addr_offset[3:0] & gfx_mode_addr_msk); |
wire [15:0] vid_ram_data_mask_nxt = ({16{gfx_mode_1_bpp_i }} & vid_ram_data_mask_shift ) | |
({16{gfx_mode_2_bpp_i }} & {{2{vid_ram_data_mask_shift[7]}}, |
{2{vid_ram_data_mask_shift[6]}}, |
{2{vid_ram_data_mask_shift[5]}}, |
{2{vid_ram_data_mask_shift[4]}}, |
{2{vid_ram_data_mask_shift[3]}}, |
{2{vid_ram_data_mask_shift[2]}}, |
{2{vid_ram_data_mask_shift[1]}}, |
{2{vid_ram_data_mask_shift[0]}}}) | |
({16{gfx_mode_4_bpp_i }} & {{4{vid_ram_data_mask_shift[3]}}, |
{4{vid_ram_data_mask_shift[2]}}, |
{4{vid_ram_data_mask_shift[1]}}, |
{4{vid_ram_data_mask_shift[0]}}}) | |
({16{gfx_mode_8_bpp_i }} & {{8{vid_ram_data_mask_shift[1]}}, |
{8{vid_ram_data_mask_shift[0]}}}) | |
({16{gfx_mode_16_bpp_i}} & {16{1'b1}} ) ; |
|
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) vid_ram_data_mask <= 16'hffff; |
else if (vid_ram_data_rd_msk) vid_ram_data_mask <= vid_ram_data_mask_nxt; |
else if (vid_ram_access_o) vid_ram_data_mask <= 16'hffff; |
|
|
endmodule // ogfx_reg_vram_if |
|
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_undefines.v" |
`endif |
/trunk/core/rtl/verilog/ogfx_reg_fifo.v
0,0 → 1,184
//---------------------------------------------------------------------------- |
// 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_backend_lut_fifo.v |
// |
// *Module Description: |
// Simple FIFO module |
// |
// *Author(s): |
// - Olivier Girard, olgirard@gmail.com |
// |
//---------------------------------------------------------------------------- |
// $Rev$ |
// $LastChangedBy$ |
// $LastChangedDate$ |
//---------------------------------------------------------------------------- |
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_defines.v" |
`endif |
|
module ogfx_reg_fifo ( |
|
// OUTPUTs |
fifo_cnt_o, // Fifo counter |
fifo_data_o, // Read data output |
fifo_done_evt_o, // Fifo has been emptied |
fifo_empty_o, // Fifo is currentely empty |
fifo_full_o, // Fifo is currentely full |
fifo_ovfl_evt_o, // Fifo overflow event |
|
// INPUTs |
mclk, // Main system clock |
puc_rst, // Main system reset |
|
fifo_data_i, // Read data input |
fifo_enable_i, // Enable fifo (flushed when disabled) |
fifo_pop_i, // Pop data from the fifo |
fifo_push_i // Push new data to the fifo |
); |
|
// OUTPUTs |
//========= |
output [3:0] fifo_cnt_o; // Fifo counter |
output [15:0] fifo_data_o; // Read data output |
output fifo_done_evt_o; // Fifo has been emptied |
output fifo_empty_o; // Fifo is currentely empty |
output fifo_full_o; // Fifo is currentely full |
output fifo_ovfl_evt_o; // Fifo overflow event |
|
// INPUTs |
//========= |
input mclk; // Main system clock |
input puc_rst; // Main system reset |
|
input [15:0] fifo_data_i; // Read data input |
input fifo_enable_i; // Enable fifo (flushed when disabled) |
input fifo_pop_i; // Pop data from the fifo |
input fifo_push_i; // Push new data to the fifo |
|
|
//============================================================================= |
// 1) WIRE, REGISTERS AND PARAMETER DECLARATION |
//============================================================================= |
|
// Some parameter(s) |
parameter FIFO_EMPTY = 4'h0, |
FIFO_FULL = 4'hf; |
|
// Others |
reg [3:0] fifo_cnt_o; |
wire [3:0] fifo_cnt_nxt; |
|
|
//============================================================================ |
// 5) FIFO COUNTER |
//============================================================================ |
|
// Control signals |
wire fifo_full_o = (fifo_cnt_o == FIFO_FULL); |
wire fifo_empty_o = (fifo_cnt_o == FIFO_EMPTY); |
wire fifo_push_int = fifo_push_i & !fifo_full_o; |
wire fifo_pop_int = fifo_pop_i & !fifo_empty_o; |
|
// Events |
assign fifo_done_evt_o = ~fifo_empty_o & (fifo_cnt_nxt == FIFO_EMPTY); |
assign fifo_ovfl_evt_o = fifo_push_i & fifo_full_o; |
|
|
// Fifo counter |
assign fifo_cnt_nxt = ~fifo_enable_i ? FIFO_EMPTY : // Initialize |
(fifo_push_int & fifo_pop_int) ? fifo_cnt_o : // Keep value (pop & push at the same time) |
fifo_push_int ? fifo_cnt_o + 3'h1 : // Push |
fifo_pop_int ? fifo_cnt_o - 3'h1 : // Pop |
fifo_cnt_o; // Hold |
|
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) fifo_cnt_o <= FIFO_EMPTY; |
else fifo_cnt_o <= fifo_cnt_nxt; |
|
|
//============================================================================ |
// 6) FIFO MEMORY & RD/WR POINTERS |
//============================================================================ |
|
// Write pointer |
reg [3:0] wr_ptr; |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) wr_ptr <= 4'h0; |
else if (~fifo_enable_i) wr_ptr <= 4'h0; |
else if (fifo_push_int) |
begin |
if (wr_ptr==(FIFO_FULL-1)) wr_ptr <= 4'h0; |
else wr_ptr <= wr_ptr + 4'h1; |
end |
|
// Memory |
reg [15:0] fifo_mem [0:15]; |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) |
begin |
fifo_mem[0] <= 16'h0000; |
fifo_mem[1] <= 16'h0000; |
fifo_mem[2] <= 16'h0000; |
fifo_mem[3] <= 16'h0000; |
fifo_mem[4] <= 16'h0000; |
fifo_mem[5] <= 16'h0000; |
fifo_mem[6] <= 16'h0000; |
fifo_mem[7] <= 16'h0000; |
fifo_mem[8] <= 16'h0000; |
fifo_mem[9] <= 16'h0000; |
fifo_mem[10] <= 16'h0000; |
fifo_mem[11] <= 16'h0000; |
fifo_mem[12] <= 16'h0000; |
fifo_mem[13] <= 16'h0000; |
fifo_mem[14] <= 16'h0000; |
fifo_mem[15] <= 16'h0000; |
end |
else if (fifo_push_int) |
begin |
fifo_mem[wr_ptr] <= fifo_data_i; |
end |
|
// Read pointer |
reg [3:0] rd_ptr; |
always @(posedge mclk or posedge puc_rst) |
if (puc_rst) rd_ptr <= 4'h0; |
else if (~fifo_enable_i) rd_ptr <= 4'h0; |
else if (fifo_pop_int) |
begin |
if (rd_ptr==(FIFO_FULL-1)) rd_ptr <= 4'h0; |
else rd_ptr <= rd_ptr + 4'h1; |
end |
|
assign fifo_data_o = fifo_mem[rd_ptr]; |
|
|
endmodule // ogfx_reg_fifo |
|
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_undefines.v" |
`endif |
/trunk/core/rtl/verilog/ogfx_ram_arbiter.v
0,0 → 1,264
//---------------------------------------------------------------------------- |
// 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_ram_arbiter.v |
// |
// *Module Description: |
// RAM arbiter for LUT and VIDEO memories |
// LUT-RAM arbitration: |
// |
// - Software interface: fixed highest priority |
// - Refresh interface: fixed lowest priority |
// |
// Video-RAM arbitration: |
// |
// - Software interface: fixed highest priority |
// - Refresh interface: round-robin with GPIO if |
// - GPU interface: round-robin with Refresh if |
// |
// *Author(s): |
// - Olivier Girard, olgirard@gmail.com |
// |
//---------------------------------------------------------------------------- |
// $Rev$ |
// $LastChangedBy$ |
// $LastChangedDate$ |
//---------------------------------------------------------------------------- |
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_defines.v" |
`endif |
|
module ogfx_ram_arbiter ( |
|
mclk, // Main system clock |
puc_rst, // Main system reset |
|
//------------------------------------------------------------ |
|
// SW interface, fixed highest priority |
lut_ram_sw_addr_i, // LUT-RAM Software address |
lut_ram_sw_din_i, // LUT-RAM Software data |
lut_ram_sw_wen_i, // LUT-RAM Software write strobe (active low) |
lut_ram_sw_cen_i, // LUT-RAM Software chip enable (active low) |
lut_ram_sw_dout_o, // LUT-RAM Software data input |
|
// Refresh-backend, fixed lowest priority |
lut_ram_refr_addr_i, // LUT-RAM Refresh address |
lut_ram_refr_din_i, // LUT-RAM Refresh data |
lut_ram_refr_wen_i, // LUT-RAM Refresh write strobe (active low) |
lut_ram_refr_cen_i, // LUT-RAM Refresh enable (active low) |
lut_ram_refr_dout_o, // LUT-RAM Refresh data output |
lut_ram_refr_dout_rdy_nxt_o, // LUT-RAM Refresh data output ready during next cycle |
|
// LUT Memory interface |
lut_ram_addr_o, // LUT-RAM address |
lut_ram_din_o, // LUT-RAM data |
lut_ram_wen_o, // LUT-RAM write strobe (active low) |
lut_ram_cen_o, // LUT-RAM chip enable (active low) |
lut_ram_dout_i, // LUT-RAM data input |
|
//------------------------------------------------------------ |
|
// SW interface, fixed highest priority |
vid_ram_sw_addr_i, // Video-RAM Software address |
vid_ram_sw_din_i, // Video-RAM Software data |
vid_ram_sw_wen_i, // Video-RAM Software write strobe (active low) |
vid_ram_sw_cen_i, // Video-RAM Software chip enable (active low) |
vid_ram_sw_dout_o, // Video-RAM Software data input |
|
// GPU interface (round-robin with refresh-backend) |
vid_ram_gpu_addr_i, // Video-RAM GPU address |
vid_ram_gpu_din_i, // Video-RAM GPU data |
vid_ram_gpu_wen_i, // Video-RAM GPU write strobe (active low) |
vid_ram_gpu_cen_i, // Video-RAM GPU chip enable (active low) |
vid_ram_gpu_dout_o, // Video-RAM GPU data input |
vid_ram_gpu_dout_rdy_nxt_o, // Video-RAM GPU data output ready during next cycle |
|
// Refresh-backend (round-robin with GPU interface) |
vid_ram_refr_addr_i, // Video-RAM Refresh address |
vid_ram_refr_din_i, // Video-RAM Refresh data |
vid_ram_refr_wen_i, // Video-RAM Refresh write strobe (active low) |
vid_ram_refr_cen_i, // Video-RAM Refresh enable (active low) |
vid_ram_refr_dout_o, // Video-RAM Refresh data output |
vid_ram_refr_dout_rdy_nxt_o, // Video-RAM Refresh data output ready during next cycle |
|
// Video Memory interface |
vid_ram_addr_o, // Video-RAM address |
vid_ram_din_o, // Video-RAM data |
vid_ram_wen_o, // Video-RAM write strobe (active low) |
vid_ram_cen_o, // Video-RAM chip enable (active low) |
vid_ram_dout_i // Video-RAM data input |
|
//------------------------------------------------------------ |
); |
|
// CLOCK/RESET |
//============= |
input mclk; // Main system clock |
input puc_rst; // Main system reset |
|
// LUT MEMORY |
//============= |
|
// SW interface, fixed highest priority |
input [`LRAM_MSB:0] lut_ram_sw_addr_i; // LUT-RAM Software address |
input [15:0] lut_ram_sw_din_i; // LUT-RAM Software data |
input lut_ram_sw_wen_i; // LUT-RAM Software write strobe (active low) |
input lut_ram_sw_cen_i; // LUT-RAM Software chip enable (active low) |
output [15:0] lut_ram_sw_dout_o; // LUT-RAM Software data input |
|
// Refresh-backend, fixed lowest priority |
input [`LRAM_MSB:0] lut_ram_refr_addr_i; // LUT-RAM Refresh address |
input [15:0] lut_ram_refr_din_i; // LUT-RAM Refresh data |
input lut_ram_refr_wen_i; // LUT-RAM Refresh write strobe (active low) |
input lut_ram_refr_cen_i; // LUT-RAM Refresh enable (active low) |
output [15:0] lut_ram_refr_dout_o; // LUT-RAM Refresh data output |
output lut_ram_refr_dout_rdy_nxt_o; // LUT-RAM Refresh data output ready during next cycle |
|
// LUT Memory interface |
output [`LRAM_MSB:0] lut_ram_addr_o; // LUT-RAM address |
output [15:0] lut_ram_din_o; // LUT-RAM data |
output lut_ram_wen_o; // LUT-RAM write strobe (active low) |
output lut_ram_cen_o; // LUT-RAM chip enable (active low) |
input [15:0] lut_ram_dout_i; // LUT-RAM data input |
|
// VIDEO MEMORY |
//============== |
|
// SW interface, fixed highest priority |
input [`VRAM_MSB:0] vid_ram_sw_addr_i; // Video-RAM Software address |
input [15:0] vid_ram_sw_din_i; // Video-RAM Software data |
input vid_ram_sw_wen_i; // Video-RAM Software write strobe (active low) |
input vid_ram_sw_cen_i; // Video-RAM Software chip enable (active low) |
output [15:0] vid_ram_sw_dout_o; // Video-RAM Software data input |
|
// GPU interface (round-robin with refresh-backend) |
input [`VRAM_MSB:0] vid_ram_gpu_addr_i; // Video-RAM GPU address |
input [15:0] vid_ram_gpu_din_i; // Video-RAM GPU data |
input vid_ram_gpu_wen_i; // Video-RAM GPU write strobe (active low) |
input vid_ram_gpu_cen_i; // Video-RAM GPU chip enable (active low) |
output [15:0] vid_ram_gpu_dout_o; // Video-RAM GPU data input |
output vid_ram_gpu_dout_rdy_nxt_o; // Video-RAM GPU data output ready during next cycle |
|
// Refresh-backend (round-robin with GPU interface) |
input [`VRAM_MSB:0] vid_ram_refr_addr_i; // Video-RAM Refresh address |
input [15:0] vid_ram_refr_din_i; // Video-RAM Refresh data |
input vid_ram_refr_wen_i; // Video-RAM Refresh write strobe (active low) |
input vid_ram_refr_cen_i; // Video-RAM Refresh enable (active low) |
output [15:0] vid_ram_refr_dout_o; // Video-RAM Refresh data output |
output vid_ram_refr_dout_rdy_nxt_o; // Video-RAM Refresh data output ready during next cycle |
|
// Video Memory interface |
output [`VRAM_MSB:0] vid_ram_addr_o; // Video-RAM address |
output [15:0] vid_ram_din_o; // Video-RAM data |
output vid_ram_wen_o; // Video-RAM write strobe (active low) |
output vid_ram_cen_o; // Video-RAM chip enable (active low) |
input [15:0] vid_ram_dout_i; // Video-RAM data input |
|
|
//============================================================================= |
// 1) WIRE, REGISTERS AND PARAMETER DECLARATION |
//============================================================================= |
|
reg gpu_is_last_owner; |
|
|
//============================================================================= |
// 2) LUT MEMORY ARBITER |
//============================================================================= |
|
// Arbitration signals |
wire sw_lram_access_granted = ~lut_ram_sw_cen_i; |
wire refr_lram_access_granted = ~sw_lram_access_granted & ~lut_ram_refr_cen_i; |
|
// LUT RAM signal muxing |
assign lut_ram_sw_dout_o = lut_ram_dout_i; |
|
assign lut_ram_refr_dout_o = lut_ram_dout_i; |
assign lut_ram_refr_dout_rdy_nxt_o = refr_lram_access_granted; |
|
assign lut_ram_addr_o = ({`LRAM_AWIDTH{ sw_lram_access_granted }} & lut_ram_sw_addr_i ) | |
({`LRAM_AWIDTH{ refr_lram_access_granted}} & lut_ram_refr_addr_i) ; |
|
assign lut_ram_din_o = ({ 16{ sw_lram_access_granted }} & lut_ram_sw_din_i ) | |
({ 16{ refr_lram_access_granted}} & lut_ram_refr_din_i ) ; |
|
assign lut_ram_wen_o = ( ~sw_lram_access_granted | lut_ram_sw_wen_i ) & |
( ~refr_lram_access_granted | lut_ram_refr_wen_i ) ; |
|
assign lut_ram_cen_o = lut_ram_sw_cen_i & lut_ram_refr_cen_i; |
|
|
//============================================================================= |
// 3) VIDEO MEMORY ARBITER |
//============================================================================= |
|
|
// Arbitration signals |
wire sw_vram_access_granted = ~vid_ram_sw_cen_i; |
wire gpu_vram_access_granted = ~sw_vram_access_granted & // No SW access |
((~vid_ram_gpu_cen_i & vid_ram_refr_cen_i) | // GPU requests alone |
(~vid_ram_gpu_cen_i & ~vid_ram_refr_cen_i & ~gpu_is_last_owner)) ; // GPU & REFR both requests (arbitration required) |
|
wire refr_vram_access_granted = ~sw_vram_access_granted & // No SW access |
(( vid_ram_gpu_cen_i & ~vid_ram_refr_cen_i) | // GPU requests alone |
(~vid_ram_gpu_cen_i & ~vid_ram_refr_cen_i & gpu_is_last_owner)) ; // GPU & REFR both requests (arbitration required) |
|
// Detect who was the last to own the RAM between the GPU and Refresh interface |
always @ (posedge mclk or posedge puc_rst) |
if (puc_rst) gpu_is_last_owner <= 1'b0; |
else if (gpu_vram_access_granted ) gpu_is_last_owner <= 1'b1; |
else if (refr_vram_access_granted) gpu_is_last_owner <= 1'b0; |
|
// Video RAM signal muxing |
assign vid_ram_sw_dout_o = vid_ram_dout_i; |
|
assign vid_ram_gpu_dout_o = vid_ram_dout_i; |
assign vid_ram_gpu_dout_rdy_nxt_o = gpu_vram_access_granted; |
|
assign vid_ram_refr_dout_o = vid_ram_dout_i; |
assign vid_ram_refr_dout_rdy_nxt_o = refr_vram_access_granted; |
|
assign vid_ram_addr_o = ({`VRAM_AWIDTH{ sw_vram_access_granted }} & vid_ram_sw_addr_i ) | |
({`VRAM_AWIDTH{ gpu_vram_access_granted }} & vid_ram_gpu_addr_i ) | |
({`VRAM_AWIDTH{ refr_vram_access_granted}} & vid_ram_refr_addr_i) ; |
|
assign vid_ram_din_o = ({ 16{ sw_vram_access_granted }} & vid_ram_sw_din_i ) | |
({ 16{ gpu_vram_access_granted }} & vid_ram_gpu_din_i ) | |
({ 16{ refr_vram_access_granted}} & vid_ram_refr_din_i ) ; |
|
assign vid_ram_wen_o = ( ~sw_vram_access_granted | vid_ram_sw_wen_i ) & |
( ~gpu_vram_access_granted | vid_ram_gpu_wen_i ) & |
( ~refr_vram_access_granted | vid_ram_refr_wen_i ) ; |
|
assign vid_ram_cen_o = vid_ram_sw_cen_i & vid_ram_gpu_cen_i & vid_ram_refr_cen_i; |
|
|
endmodule // ogfx_ram_arbiter |
|
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_undefines.v" |
`endif |
/trunk/core/rtl/verilog/ogfx_backend.v
0,0 → 1,217
//---------------------------------------------------------------------------- |
// 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_backend.v |
// |
// *Module Description: |
// Backend module of the graphic controller. |
// The purpose of this block is to: |
// |
// - fetch the data from the specified frame buffer |
// - convert data depending on selected video mode |
// |
// *Author(s): |
// - Olivier Girard, olgirard@gmail.com |
// |
//---------------------------------------------------------------------------- |
// $Rev$ |
// $LastChangedBy$ |
// $LastChangedDate$ |
//---------------------------------------------------------------------------- |
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_defines.v" |
`endif |
|
module ogfx_backend ( |
|
// OUTPUTs |
refresh_data_o, // Display refresh data |
refresh_data_ready_o, // Display refresh new data is ready |
|
vid_ram_addr_o, // Video-RAM refresh address |
vid_ram_cen_o, // Video-RAM refresh enable (active low) |
|
`ifdef WITH_PROGRAMMABLE_LUT |
lut_ram_addr_o, // LUT-RAM refresh address |
lut_ram_cen_o, // LUT-RAM refresh enable (active low) |
`endif |
|
// INPUTs |
mclk, // Main system clock |
puc_rst, // Main system reset |
|
display_width_i, // Display width |
display_height_i, // Display height |
display_size_i, // Display size (number of pixels) |
display_y_swap_i, // Display configuration: swap Y axis (horizontal symmetry) |
display_x_swap_i, // Display configuration: swap X axis (vertical symmetry) |
display_cl_swap_i, // Display configuration: swap column/lines |
|
gfx_mode_i, // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp) |
|
`ifdef WITH_PROGRAMMABLE_LUT |
lut_ram_dout_i, // LUT-RAM data output |
lut_ram_dout_rdy_nxt_i, // LUT-RAM data output ready during next cycle |
`endif |
|
vid_ram_dout_i, // Video-RAM data output |
vid_ram_dout_rdy_nxt_i, // Video-RAM data output ready during next cycle |
|
refresh_active_i, // Display refresh on going |
refresh_data_request_i, // Display refresh new data request |
refresh_frame_base_addr_i, // Refresh frame base address |
refresh_lut_select_i // Refresh LUT bank selection |
); |
|
// OUTPUTs |
//========= |
output [15:0] refresh_data_o; // Display refresh data |
output refresh_data_ready_o; // Display refresh new data is ready |
|
output [`VRAM_MSB:0] vid_ram_addr_o; // Video-RAM refresh address |
output vid_ram_cen_o; // Video-RAM refresh enable (active low) |
|
`ifdef WITH_PROGRAMMABLE_LUT |
output [`LRAM_MSB:0] lut_ram_addr_o; // LUT-RAM refresh address |
output lut_ram_cen_o; // LUT-RAM refresh enable (active low) |
`endif |
|
// INPUTs |
//========= |
input mclk; // Main system clock |
input puc_rst; // Main system reset |
|
input [`LPIX_MSB:0] display_width_i; // Display width |
input [`LPIX_MSB:0] display_height_i; // Display height |
input [`SPIX_MSB:0] display_size_i; // Display size (number of pixels) |
input display_y_swap_i; // Display configuration: swap Y axis (horizontal symmetry) |
input display_x_swap_i; // Display configuration: swap X axis (vertical symmetry) |
input display_cl_swap_i; // Display configuration: swap column/lines |
|
input [2:0] gfx_mode_i; // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp) |
|
`ifdef WITH_PROGRAMMABLE_LUT |
input [15:0] lut_ram_dout_i; // LUT-RAM data output |
input lut_ram_dout_rdy_nxt_i; // LUT-RAM data output ready during next cycle |
`endif |
|
input [15:0] vid_ram_dout_i; // Video-RAM data output |
input vid_ram_dout_rdy_nxt_i; // Video-RAM data output ready during next cycle |
|
input refresh_active_i; // Display refresh on going |
input refresh_data_request_i; // Display refresh new data request |
input [`APIX_MSB:0] refresh_frame_base_addr_i; // Refresh frame base address |
input [1:0] refresh_lut_select_i; // Refresh LUT bank selection |
|
|
//============================================================================= |
// 1) WIRE, REGISTERS AND PARAMETER DECLARATION |
//============================================================================= |
|
// Wires |
wire [15:0] frame_data; |
wire frame_data_ready; |
wire frame_data_request; |
|
|
//============================================================================ |
// 2) FRAME MEMORY ACCESS |
//============================================================================ |
|
ogfx_backend_frame_fifo ogfx_backend_frame_fifo_inst ( |
|
// OUTPUTs |
.frame_data_o ( frame_data ), // Frame data |
.frame_data_ready_o ( frame_data_ready ), // Frame data ready |
|
.vid_ram_addr_o ( vid_ram_addr_o ), // Video-RAM address |
.vid_ram_cen_o ( vid_ram_cen_o ), // Video-RAM enable (active low) |
|
// INPUTs |
.mclk ( mclk ), // Main system clock |
.puc_rst ( puc_rst ), // Main system reset |
|
.display_width_i ( display_width_i ), // Display width |
.display_height_i ( display_height_i ), // Display height |
.display_size_i ( display_size_i ), // Display size (number of pixels) |
.display_y_swap_i ( display_y_swap_i ), // Display configuration: swap Y axis (horizontal symmetry) |
.display_x_swap_i ( display_x_swap_i ), // Display configuration: swap X axis (vertical symmetry) |
.display_cl_swap_i ( display_cl_swap_i ), // Display configuration: swap column/lines |
|
.frame_data_request_i ( frame_data_request ), // Request for next frame data |
|
.gfx_mode_i ( gfx_mode_i ), // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp) |
|
.vid_ram_dout_i ( vid_ram_dout_i ), // Video-RAM data output |
.vid_ram_dout_rdy_nxt_i ( vid_ram_dout_rdy_nxt_i ), // Video-RAM data output ready during next cycle |
|
.refresh_active_i ( refresh_active_i ), // Display refresh on going |
.refresh_frame_base_addr_i ( refresh_frame_base_addr_i ) // Refresh frame base address |
); |
|
|
//============================================================================ |
// 3) LUT MEMORY ACCESS |
//============================================================================ |
|
ogfx_backend_lut_fifo ogfx_backend_lut_fifo_inst ( |
|
// OUTPUTs |
.frame_data_request_o ( frame_data_request ), // Request for next frame data |
|
.refresh_data_o ( refresh_data_o ), // Display Refresh data |
.refresh_data_ready_o ( refresh_data_ready_o ), // Display Refresh data ready |
|
`ifdef WITH_PROGRAMMABLE_LUT |
.lut_ram_addr_o ( lut_ram_addr_o ), // LUT-RAM address |
.lut_ram_cen_o ( lut_ram_cen_o ), // LUT-RAM enable (active low) |
`endif |
|
// INPUTs |
.mclk ( mclk ), // Main system clock |
.puc_rst ( puc_rst ), // Main system reset |
|
.frame_data_i ( frame_data ), // Frame data |
.frame_data_ready_i ( frame_data_ready ), // Frame data ready |
|
.gfx_mode_i ( gfx_mode_i ), // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp) |
|
`ifdef WITH_PROGRAMMABLE_LUT |
.lut_ram_dout_i ( lut_ram_dout_i ), // LUT-RAM data output |
.lut_ram_dout_rdy_nxt_i ( lut_ram_dout_rdy_nxt_i ), // LUT-RAM data output ready during next cycle |
`endif |
|
.refresh_active_i ( refresh_active_i ), // Display refresh on going |
.refresh_data_request_i ( refresh_data_request_i ), // Request for next refresh data |
.refresh_lut_select_i ( refresh_lut_select_i ) // Refresh LUT bank selection |
); |
|
|
endmodule // ogfx_backend |
|
`ifdef OGFX_NO_INCLUDE |
`else |
`include "openGFX430_undefines.v" |
`endif |