Commit c0a7f6f6 authored by Iulian Gheorghiu's avatar Iulian Gheorghiu

Update

parent 91689147
/*----------------------------------------------------------------------------/
/ This IP is a Graphic 2D accelerator interface. /
/-----------------------------------------------------------------------------/
/
/ Copyright (C) 2018 Iulian Gheorghiu (morgoth.creator@gmail.com), all right reserved.
/
/ This IP file is an open source software. Redistribution and use of this IP in
/ source and binary forms, with or without modification, are permitted provided
/ that the following condition is met:
/ 1. Redistributions of source code must retain the above copyright notice,
/ this condition and the following disclaimer.
/
/ This software is provided by the copyright holder and contributors "AS IS"
/ and any warranties related to this software are DISCLAIMED.
/ The copyright owner or contributors be NOT LIABLE for any damages caused
/ by use of this software.
/----------------------------------------------------------------------------*/
`timescale 1ns / 1ps
`include "io_s_h.v"
`define GFX_ACCEL_IDLE 0
`define GFX_ACCEL_VRAM_ACCESS 1
`define GFX_ACCEL_PIXEL_LOAD 2
`define GFX_ACCEL_PIXEL 3
`define GFX_ACCEL_CTRL_ACCESS 4
`define GFX_ACCEL_FILL_RECT 5
/*
* The first sixteen addresses after ADDRESS parameter address are used by LCD IP, the next sixteen addresses are used by this IP.
*/
module gfx_accel #(
parameter DISPLAY_CFG = "1440_900_60_DISPLAY_106_50_Mhz",
parameter DEBUG = "",//"PATERN_RASTER"
parameter ADDRESS = 0,
parameter BUS_VRAM_ADDR_LEN = 24,
parameter BUS_VRAM_DATA_LEN = 8,
parameter BUS_ADDR_DATA_LEN = 16,
parameter ACCEL_DINAMIC_CONFIG = "FALSE",
parameter LCD_DINAMIC_CONFIG = "FALSE",
parameter VRAM_BASE_ADDRESS_CONF = 0,
parameter H_RES_CONF = 800,
parameter H_BACK_PORCH_CONF = 46,
parameter H_FRONT_PORCH_CONF = 210,
parameter H_PULSE_WIDTH_CONF = 2,
parameter V_RES_CONF = 480,
parameter V_BACK_PORCH_CONF = 23,
parameter V_FRONT_PORCH_CONF = 22,
parameter V_PULSE_WIDTH_CONF = 2,
parameter PIXEL_SIZE_CONF = 16,
parameter HSYNK_INVERTED_CONF = 1'b1,
parameter VSYNK_INVERTED_CONF = 1'b1,
parameter DATA_ENABLE_INVERTED_CONF = 1'b0,
parameter DEDICATED_VRAM_SIZE = 0
)(
input rst,
input ctrl_clk,
input [BUS_ADDR_DATA_LEN-1:0]ctrl_addr,
input ctrl_wr,
input ctrl_rd,
input [7:0]ctrl_data_in,
output reg [7:0]ctrl_data_out,
inout [BUS_VRAM_ADDR_LEN-1:0]vmem_addr,
input [BUS_VRAM_DATA_LEN-1:0]vmem_in,
output [BUS_VRAM_DATA_LEN-1:0]vmem_out,
input vmem_rd,
input vmem_wr,
input lcd_clk,
output lcd_h_synk,
output lcd_v_synk,
output [7:0]lcd_r,
output [7:0]lcd_g,
output [7:0]lcd_b,
output lcd_de
);
wire cs_int = ctrl_addr >= ADDRESS + 16 && ctrl_addr < (ADDRESS + 32);
wire rd_int = cs_int && ctrl_rd;
wire wr_int = cs_int && ctrl_wr;
wire [BUS_VRAM_ADDR_LEN-1:0]lcd_vmem_addr;
wire [BUS_VRAM_DATA_LEN-1:0]lcd_vmem_in;
wire [BUS_VRAM_DATA_LEN-1:0]lcd_vmem_out;
wire lcd_vmem_rd;
wire lcd_vmem_wr;
wire [7:0]ctrl_data_out_;
lcd # (
.MASTER("FALSE"),
.DISPLAY_CFG(DISPLAY_CFG),
.DEBUG(DEBUG),
.ADDRESS(ADDRESS),
.BUS_VRAM_ADDR_LEN(BUS_VRAM_ADDR_LEN),
.BUS_VRAM_DATA_LEN(BUS_VRAM_DATA_LEN),
.BUS_ADDR_DATA_LEN(BUS_ADDR_DATA_LEN),
.DINAMIC_CONFIG(LCD_DINAMIC_CONFIG),
.VRAM_BASE_ADDRESS_CONF(0),
.H_RES_CONF(H_RES_CONF),
.H_BACK_PORCH_CONF(H_BACK_PORCH_CONF),
.H_FRONT_PORCH_CONF(H_FRONT_PORCH_CONF),
.H_PULSE_WIDTH_CONF(H_PULSE_WIDTH_CONF),
.V_RES_CONF(V_RES_CONF),
.V_BACK_PORCH_CONF(V_BACK_PORCH_CONF),
.V_FRONT_PORCH_CONF(V_FRONT_PORCH_CONF),
.V_PULSE_WIDTH_CONF(V_PULSE_WIDTH_CONF),
.PIXEL_SIZE_CONF(PIXEL_SIZE_CONF),
.HSYNK_INVERTED_CONF(HSYNK_INVERTED_CONF),
.VSYNK_INVERTED_CONF(VSYNK_INVERTED_CONF),
.DATA_ENABLE_INVERTED_CONF(DATA_ENABLE_INVERTED_CONF),
.DEDICATED_VRAM_SIZE(DEDICATED_VRAM_SIZE)
)lcd_inst(
.rst(rst),
.ctrl_clk(ctrl_clk),
.ctrl_addr(ctrl_addr),
.ctrl_wr(ctrl_wr),
.ctrl_rd(ctrl_rd),
.ctrl_data_in(ctrl_data_in),
.ctrl_data_out(ctrl_data_out_),
.vmem_addr(lcd_vmem_addr),
.vmem_in(lcd_vmem_in),
.vmem_out(lcd_vmem_out),
.vmem_rd(lcd_vmem_rd),
.vmem_wr(lcd_vmem_wr),
.lcd_clk(lcd_clk),
.lcd_h_synk(lcd_h_synk),
.lcd_v_synk(lcd_v_synk),
.lcd_r(lcd_r),
.lcd_g(lcd_g),
.lcd_b(lcd_b),
.lcd_de(lcd_de)
);
reg [7:0]CMD;
reg [15:0]CLIP_X_MIN;
reg [15:0]CLIP_X_MAX;
reg [15:0]CLIP_Y_MIN;
reg [15:0]CLIP_Y_MAX;
reg [31:0]COLOR;
reg [7:0]cmd_int;
reg [15:0]clip_x_min_int;
reg [15:0]clip_x_max_int;
reg [15:0]clip_y_min_int;
reg [15:0]clip_y_max_int;
reg [31:0]color;
reg [15:0]x_xnt_int;
reg [15:0]y_xnt_int;
reg [7:0]tmp_write;
reg [7:0]color_byte_2;
reg [7:0]color_byte_3;
reg direct_vram_access;
reg new_cmd;
always @ (posedge ctrl_clk or posedge rst)
begin
if(rst)
begin
CMD <= 8'h0;
CLIP_X_MIN <= 16'h0;
CLIP_X_MAX <= 16'h0;
CLIP_Y_MIN <= 16'h0;
CLIP_Y_MAX <= 16'h0;
cmd_int <= 8'h0;
clip_x_min_int <= 16'h0;
clip_x_max_int <= 16'h0;
clip_y_min_int <= 16'h0;
clip_y_max_int <= 16'h0;
x_xnt_int <= 16'h0;
y_xnt_int <= 16'h0;
direct_vram_access <= 1'h0;
new_cmd <= 1'h0;
end
else
begin
if(wr_int && !CMD)
begin
case(ctrl_addr[4:0])
'd16: CMD <= ctrl_data_in;
'd18: CLIP_X_MIN <= {tmp_write, ctrl_data_in};
'd19: tmp_write <= ctrl_data_in;
'd20: CLIP_X_MAX <= {tmp_write, ctrl_data_in};
'd21: tmp_write <= ctrl_data_in;
'd22: CLIP_Y_MIN <= {tmp_write, ctrl_data_in};
'd23: tmp_write <= ctrl_data_in;
'd24: CLIP_Y_MAX <= {tmp_write, ctrl_data_in};
'd25: tmp_write <= ctrl_data_in;
'd26: COLOR <= {color_byte_3, color_byte_2, tmp_write, ctrl_data_in};
'd27: tmp_write <= ctrl_data_in;
'd28: color_byte_2 <= ctrl_data_in;
'd29: color_byte_3 <= ctrl_data_in;
endcase
end
else if(!cmd_int && CMD)
begin
cmd_int <= CMD;
clip_x_min_int <= CLIP_X_MIN;
clip_x_max_int <= CLIP_X_MAX;
clip_y_min_int <= CLIP_Y_MIN;
clip_y_max_int <= CLIP_Y_MAX;
x_xnt_int <= CLIP_X_MIN;
y_xnt_int <= CLIP_Y_MIN;
CMD <= 'h0;
color <= COLOR;
new_cmd <= 1'b1;
end
else
begin
case(cmd_int)
`GFX_ACCEL_VRAM_ACCESS:
begin
direct_vram_access <= 1'b1;
cmd_int <= 'h0;
end
`GFX_ACCEL_CTRL_ACCESS:
begin
direct_vram_access <= 1'b0;
cmd_int <= 'h0;
end
`GFX_ACCEL_PIXEL_LOAD:
begin
x_xnt_int <= CLIP_X_MIN;
y_xnt_int <= CLIP_Y_MIN;
color <= COLOR;
if(x_xnt_int >= clip_x_max_int)
begin
x_xnt_int <= clip_x_min_int;
y_xnt_int <= x_xnt_int + 1;
end
cmd_int <= 'h0;
end
`GFX_ACCEL_PIXEL:
begin
color <= COLOR;
if(x_xnt_int >= clip_x_max_int)
begin
x_xnt_int <= clip_x_min_int;
y_xnt_int <= x_xnt_int + 1;
end
cmd_int <= 'h0;
end
`GFX_ACCEL_FILL_RECT:
begin
if(~new_cmd)
begin
if(x_xnt_int >= clip_x_max_int && y_xnt_int >= clip_y_max_int)
begin
cmd_int <= 'h0;
end
else
begin
if(x_xnt_int >= clip_x_max_int)
begin
x_xnt_int <= clip_x_min_int;
y_xnt_int <= x_xnt_int + 1;
end
end
end
end
endcase
if(cmd_int && new_cmd)
begin
new_cmd <= 1'b0;
end
end
end
end
always @ *
begin
if(rd_int)
begin
case(ctrl_addr[4:0])
'd16: ctrl_data_out <= CMD;
default: ctrl_data_out <= 'hz;
endcase
end
else
begin
ctrl_data_out <= ctrl_data_out_;
end
end
assign lcd_vmem_addr = direct_vram_access ? vmem_addr : (x_xnt_int * H_RES_CONF) + y_xnt_int;
assign lcd_vmem_in = direct_vram_access ? vmem_in : color;
assign vmem_out = direct_vram_access ? vmem_out : 'hz;
assign lcd_vmem_rd = direct_vram_access ? vmem_rd : 1'h0;
assign lcd_vmem_wr = direct_vram_access ? vmem_wr : |cmd_int;
endmodule
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment