1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-01-20 09:44:38 +00:00
Gehstock.Mist_FPGA/common/Video/PIXEL_DISPLAY.v
2019-07-22 23:42:05 +02:00

297 lines
8.1 KiB
Verilog

module PIXEL_DISPLAY (
pixel_clock,
reset,
show_border,
// mode
ag,
gm,
css,
// text
char_column,
char_line,
subchar_line,
subchar_pixel,
// graph
graph_pixel,
graph_line_2x,
graph_line_3x,
// vram
vram_rd_enable,
vram_addr,
vram_data,
// vga
vga_red,
vga_green,
vga_blue
);
input pixel_clock;
input reset;
input show_border;
// mode
input ag;
input [2:0] gm;
input css;
// text
input [6:0] char_column; // character number on the current line
input [6:0] char_line; // line number on the screen
input [4:0] subchar_line; // the line number within a character block 0-8
input [3:0] subchar_pixel; // the pixel number within a character block 0-8
// graph
input [8:0] graph_pixel; // pixel number on the current line
input [9:0] graph_line_2x; // line number on the screen
input [9:0] graph_line_3x; // line number on the screen
output vram_rd_enable;
output reg [12:0] vram_addr;
input [7:0] vram_data;
output [7:0] vga_red;
output [7:0] vga_green;
output [7:0] vga_blue;
//// Label Definitions ////
// Note: all labels must match their defined length--shorter labels will be padded with solid blocks,
// and longer labels will be truncated
// 48 character label for the example text
wire pixel_on; // high => output foreground color, low => output background color
// 8p 代表每个点占用VGA水平 8 pixel
// 2bit 代表每个点取2位值
wire [1:0] pixel_8p_2bit; // high => output foreground color, low => output background color
wire [1:0] pixel_4p_2bit; // high => output foreground color, low => output background color
wire pixel_4p_1bit; // high => output foreground color, low => output background color
wire pixel_2p_1bit; // high => output foreground color, low => output background color
reg [7:0] latched_vram_data; // the data that will be written to character memory at the clock rise
// 锁存数据用于选择调色板
reg [7:0] latched_palette_data;
assign vram_rd_enable = pixel_clock;
reg [23:0] latched_vga_rgb;
wire [23:0] vga_rgb;
// write the appropriate character data to memory
always @ (posedge pixel_clock) begin
if(ag==1'b0)
begin
if(subchar_pixel==4'b0001)
vram_addr <= {4'b0,char_line[3:0], char_column[4:0]};
// 对于同步sram需要等待 1 个时钟周期
if(subchar_pixel==4'b0011)
latched_vram_data <= vram_data;
if(graph_pixel[3:0]==4'b0110)
latched_palette_data <= latched_vram_data;
end
else
begin
case(gm)
3'b000:
begin
// 64 x 64 x 4 gm: 000
if(graph_pixel[4:0]==5'b00001)
vram_addr <= {3'b0, graph_line_3x[9:4], graph_pixel[8:5]};
// 对于同步sram需要等待 1 个时钟周期
if(graph_pixel[4:0]==5'b00011)
latched_vram_data <= vram_data;
end
3'b001:
begin
// 128 x 64 x 2 gm: 001
if(graph_pixel[4:0]==5'b00001)
vram_addr <= {3'b0, graph_line_3x[9:4], graph_pixel[8:5]};
// 对于同步sram需要等待 1 个时钟周期
if(graph_pixel[4:0]==5'b00011)
latched_vram_data <= vram_data;
end
3'b011:
begin
// 128 x 96 x 2 gm: 011
if(graph_pixel[4:0]==5'b00001)
vram_addr <= {2'b0, graph_line_2x[9:3], graph_pixel[8:5]};
// 对于同步sram需要等待 1 个时钟周期
if(graph_pixel[4:0]==5'b00011)
latched_vram_data <= vram_data;
end
3'b100:
begin
// 128 x 96 x 4 gm: 100
if(graph_pixel[3:0]==4'b0001)
vram_addr <= {1'b0, graph_line_2x[8:1], graph_pixel[8:4]};
// 对于同步sram需要等待 1 个时钟周期
if(graph_pixel[3:0]==4'b0011)
latched_vram_data <= vram_data;
end
3'b101:
begin
// 128 x 192 x 2 gm: 101
if(graph_pixel[4:0]==5'b00001)
vram_addr <= {1'b0, graph_line_2x[9:1], graph_pixel[8:5]};
// 对于同步sram需要等待 1 个时钟周期
if(graph_pixel[4:0]==5'b00011)
latched_vram_data <= vram_data;
end
3'b110:
begin
// 128 x 192 x 4 gm: 110
if(graph_pixel[3:0]==4'b0001)
vram_addr <= {graph_line_2x[9:1], graph_pixel[8:4]};
// 对于同步sram需要等待 1 个时钟周期
if(graph_pixel[3:0]==4'b0011)
latched_vram_data <= vram_data;
end
3'b111:
begin
// 256 x 192 x 2 gm: 111
if(graph_pixel[3:0]==4'b0001)
vram_addr <= {graph_line_2x[9:1], graph_pixel[8:4]};
// 对于同步sram需要等待 1 个时钟周期
if(graph_pixel[3:0]==4'b0011)
latched_vram_data <= vram_data;
end
default:
begin
// 128 x 64 x 4 gm: 010
if(graph_pixel[3:0]==4'b0001)
vram_addr <= {2'b0,graph_line_3x[9:3], graph_pixel[8:4]};
//vram_addr <= {2'b0,graph_line_3x[8:3], graph_pixel[6:2]};
// 对于同步sram需要等待 1 个时钟周期
if(graph_pixel[3:0]==4'b0011)
latched_vram_data <= vram_data;
end
endcase
end
latched_vga_rgb <= vga_rgb;
end
// palette
/*
位\色 绿 黄 蓝 红 浅黄 浅蓝 紫 橙
D6 0 0 0 0 1 1 1 1
D5 0 0 1 1 0 0 1 1
D4 0 1 0 1 0 1 0 1
0x07 0xff 0x00 // GREEN
0xff 0xff 0x00 // YELLOW
0x3b 0x08 0xff // BLUE
0xcc 0x00 0x3b // RED
0xff 0xff 0xff // BUFF
0x07 0xe3 0x99 // CYAN
0xff 0x1c 0xff // MAGENTA
0xff 0x81 0x00 // ORANGE
0x00 0x00 0x00 // BLACK
0x07 0xff 0x00 // GREEN
0x3b 0x08 0xff // BLUE
0xff 0xff 0xff // BUFF
*/
wire [2:0] palette_bit_graph;
wire [23:0] palette_rgb_border = (~ag)?24'h000000: // 字符模式背景
(css)?24'hffffff:24'h07ff00; // 图形模式背景
wire [23:0] palette_rgb_pixel = 24'h000000;
wire [23:0] palette_rgb_background = 24'h07ff00;
// 64 x 64 x 4 gm: 000
// 128 x 64 x 2 gm: 001
// 128 x 64 x 4 gm: 010
// 128 x 96 x 2 gm: 011
// 128 x 96 x 4 gm: 100
// 128 x 192 x 2 gm: 101
// 128 x 192 x 4 gm: 110
// 256 x 192 x 2 gm: 111
//assign palette_bit_graph = (ag)? {css, pixel_4p_2bit} : latched_palette_data[6:4];
assign palette_bit_graph = (~ag) ? latched_palette_data[6:4] :
(gm==3'b000) ? {css, pixel_8p_2bit } :
(gm==3'b001) ? {css, pixel_4p_1bit, pixel_4p_1bit } :
(gm==3'b010) ? {css, pixel_4p_2bit } :
(gm==3'b011) ? {css, pixel_4p_1bit, pixel_4p_1bit } :
(gm==3'b100) ? {css, pixel_4p_2bit } :
(gm==3'b101) ? {css, pixel_4p_1bit, pixel_4p_1bit } :
(gm==3'b110) ? {css, pixel_4p_2bit } :
{css, pixel_2p_1bit, pixel_2p_1bit } ;
wire [23:0] palette_rgb_graph = (palette_bit_graph==3'b000) ? 24'h07ff00 : // GREEN
(palette_bit_graph==3'b001) ? 24'hffff00 : // YELLOW
(palette_bit_graph==3'b010) ? 24'h3b08ff : // BLUE
(palette_bit_graph==3'b011) ? 24'hcc003b : // RED
(palette_bit_graph==3'b100) ? 24'hffffff : // BUFF
(palette_bit_graph==3'b101) ? 24'h07e399 : // CYAN
(palette_bit_graph==3'b110) ? 24'hff1cff : // MAGENTA
24'hff8100 ; // ORANGE
/*
24'h000000 // BLACK
24'h07ff00 // GREEN
24'h3b08ff // BLUE
24'hffffff // BUFF
*/
// use the result of the character generator module to choose between the foreground and background color
assign vga_rgb = (show_border) ? palette_rgb_border :
(ag) ? palette_rgb_graph :
(~pixel_on) ? palette_rgb_pixel :
(latched_palette_data[7]) ? palette_rgb_graph : palette_rgb_background;
assign vga_red = latched_vga_rgb[23:16];
assign vga_green = latched_vga_rgb[15:8];
assign vga_blue = latched_vga_rgb[7:0];
// the character generator block includes the character RAM
// and the character generator ROM
CHAR_GEN CHAR_GEN
(
.reset(reset), // reset signal
.char_code(latched_vram_data),
.subchar_line(subchar_line), // current line of pixels within current character
.subchar_pixel(subchar_pixel), // current column of pixels withing current character
.pixel_clock(pixel_clock), // read clock
.pixel_on(pixel_on) // read data
);
PIXEL_GEN PIXEL_GEN
(
.reset(reset), // reset signal
.pixel_code(latched_vram_data),
.graph_pixel(graph_pixel), // current column of pixels withing current character
.pixel_clock(pixel_clock), // read clock
.pixel_8p_2bit(pixel_8p_2bit), // 64x64x4
.pixel_4p_2bit(pixel_4p_2bit), // 128x64x4 128x96x4 128x192x4
.pixel_4p_1bit(pixel_4p_1bit), // 128x64x2 128x96x2 128x192x2
.pixel_2p_1bit(pixel_2p_1bit) // 256x192x2
);
endmodule //CHAR_DISPLAY