aboutsummaryrefslogtreecommitdiff
path: root/vga-core/vga_address_translator.sv
diff options
context:
space:
mode:
Diffstat (limited to 'vga-core/vga_address_translator.sv')
-rw-r--r--vga-core/vga_address_translator.sv39
1 files changed, 39 insertions, 0 deletions
diff --git a/vga-core/vga_address_translator.sv b/vga-core/vga_address_translator.sv
new file mode 100644
index 0000000..cc63fac
--- /dev/null
+++ b/vga-core/vga_address_translator.sv
@@ -0,0 +1,39 @@
+// synopsys translate_off
+`timescale 1 ps / 1 ps
+// synopsys translate_on
+
+/* This module converts a user specified coordinates into a memory address.
+ * The output of the module depends on the resolution set by the user.
+ */
+module vga_address_translator(x, y, mem_address);
+
+ parameter RESOLUTION = "320x240";
+ /* Set this parameter to "160x120" or "320x240". It will cause the VGA adapter to draw each dot on
+ * the screen by using a block of 4x4 pixels ("160x120" resolution) or 2x2 pixels ("320x240" resolution).
+ * It effectively reduces the screen resolution to an integer fraction of 640x480. It was necessary
+ * to reduce the resolution for the Video Memory to fit within the on-chip memory limits.
+ */
+
+ input [((RESOLUTION == "320x240") ? (8) : (7)):0] x;
+ input [((RESOLUTION == "320x240") ? (7) : (6)):0] y;
+ output reg [((RESOLUTION == "320x240") ? (16) : (14)):0] mem_address;
+
+ /* The basic formula is address = y*WIDTH + x;
+ * For 320x240 resolution we can write 320 as (256 + 64). Memory address becomes
+ * (y*256) + (y*64) + x;
+ * This simplifies multiplication a simple shift and add operation.
+ * A leading 0 bit is added to each operand to ensure that they are treated as unsigned
+ * inputs. By default the use a '+' operator will generate a signed adder.
+ * Similarly, for 160x120 resolution we write 160 as 128+32.
+ */
+ wire [16:0] res_320x240 = ({1'b0, y, 8'd0} + {1'b0, y, 6'd0} + {1'b0, x});
+ wire [15:0] res_160x120 = ({1'b0, y, 7'd0} + {1'b0, y, 5'd0} + {1'b0, x});
+
+ always @(*)
+ begin
+ if (RESOLUTION == "320x240")
+ mem_address = res_320x240;
+ else
+ mem_address = res_160x120[14:0];
+ end
+endmodule