Below is the latest version of the VGA write pipe. It's a bit messy
because it's not production code but rather something I need the
experts to look at to make sure I have the details right.
Also, I've made further changes to PCI, but I haven't bothered to post
them because I've only gotten one offer to help so far. If someone
has worked with PCI before or has a background in chip design but does
not have a copy of the spec, talk to me, and I'll get you a legal copy
so you can help. The trouble is that these copies are scarce, so I
can't give them out to anyone who does not make a solid commitment to
work on it.
// VGA write pipe
// Copyright 2005, Timothy Miller
// LGPL license
module vga_write_pipe(
clock,
source_byte,
read_plane0,
read_plane1,
read_plane2,
read_plane3,
out_plane_0,
out_plane_1,
out_plane_2,
out_plane_3,
rotate,
enable_set_reset,
set_reset,
graphics_mode,
logic_op,
write_enable,
bit_mask
);
input clock;
input [7:0] source_byte;
input [7:0] read_plane0, read_plane1, read_plane2, read_plane3;
output [7:0] out_plane_0, out_plane_1, out_plane_2, out_plane_3;
reg [7:0] out_plane_0, out_plane_1, out_plane_2, out_plane_3;
input [2:0] rotate;
input [3:0] enable_set_reset, set_reset;
input [1:0] graphics_mode;
input [1:0] logic_op;
input [3:0] write_enable;
input [7:0] bit_mask;
// NOTE: Although x86 is little-endian and bit zero should be on the left,
// VGA puts the high bit on the left.
// Stage 1
// Peform right shift
wire [15:0] shift0 = {source_byte, 8'b0} >> rotate;
wire [7:0] shift1 = shift0[15:8] | shift[7:0];
reg [7:0] source_plane0a;
always @(posedge clock) begin
plane0a <= shift1;
end
reg [3:0] set_reset_selected;
always @(posedge clock) begin
set_reset_selected <= (graphics_mode == 2) ? source_byte[3:0] : set_reset;
end
// Stage 2
wire [3:0] enable_set_reset0 = {4{graphics_mode[1]}} | enable_set_reset;
reg [7:0] plane0b, plane1b, plane2b, plane3b, source_b;
always @(posedge clock) begin
source_b <= plane0a;
plane3b <= enable_set_reset0[3] ? {8{set_reset_selected[3]}} : plane0a;
plane2b <= enable_set_reset0[2] ? {8{set_reset_selected[2]}} : plane0a;
plane1b <= enable_set_reset0[1] ? {8{set_reset_selected[1]}} : plane0a;
plane0b <= enable_set_reset0[0] ? {8{set_reset_selected[0]}} : plane0a;
end
// Stage 3
reg [7:0] plane0c, plane1c, plane2c, plane3c;
always @(posedge clock) begin
case (logic_op)
0: begin
plane0c <= plane0b;
plane1c <= plane1b;
plane2c <= plane2b;
plane3c <= plane3b;
end
1: begin
plane0c <= plane0b & read_plane0;
plane1c <= plane1b & read_plane1;
plane2c <= plane2b & read_plane2;
plane3c <= plane3b & read_plane3;
end
2: begin
plane0c <= plane0b | read_plane0;
plane1c <= plane1b | read_plane1;
plane2c <= plane2b | read_plane2;
plane3c <= plane3b | read_plane3;
end
3: begin
plane0c <= plane0b ^ read_plane0;
plane1c <= plane1b ^ read_plane1;
plane2c <= plane2b ^ read_plane2;
plane3c <= plane3b ^ read_plane3;
end
endcase
end
reg [7:0] bitmask_select;
always @(posedge clock) begin
case (graphics_mode)
0, 2: begin
bitmask_select <= bit_mask;
end
1: begin
bitmask_select <= 0;
end
3: begin
bitmask_select <= bit_mask & source_b;
end
endcase
end
// Stage 4
always @(posedge clock) begin
out_plane_0 <= (bitmask_select & plane0c) | (~bitmask_select & read_plane0);
out_plane_1 <= (bitmask_select & plane1c) | (~bitmask_select & read_plane1);
out_plane_2 <= (bitmask_select & plane2c) | (~bitmask_select & read_plane2);
out_plane_3 <= (bitmask_select & plane3c) | (~bitmask_select & read_plane3);
end
// Note: write-enable is handled as byte-enable in the memory controller
endmodule
_______________________________________________
Open-graphics mailing list
[email protected]
http://lists.duskglow.com/mailman/listinfo/open-graphics
List service provided by Duskglow Consulting, LLC (www.duskglow.com)