mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-01-20 09:44:38 +00:00
297 lines
8.1 KiB
Verilog
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
|