From 11cea6b1cfe873e1af71711eff62620f631a7965 Mon Sep 17 00:00:00 2001 From: John Bintz Date: Sun, 14 Jul 2024 20:34:18 -0400 Subject: [PATCH] More stuff --- .gitignore | 2 + Makefile | 8 +- build_image.rb | 101 + double_dabble.rb | 37 + double_dabble_counters.bin | Bin 0 -> 32220 bytes double_dabble_counters.v | 136 + image_data.txt | 4800 +++++++++++++++++++++++++++++++++++ image_index_to_color.v | 94 + image_ram.v | 92 + image_ram_dat.txt | 2 + palette_data.txt | 32 + pong_runner.bin | Bin 0 -> 32220 bytes vga_add_porches_to_output.v | 34 +- vga_current_beam_position.v | 8 +- vga_image_renderer.bin | Bin 0 -> 32220 bytes vga_image_renderer.v | 81 + vga_image_renderer_top.bin | Bin 0 -> 32220 bytes vga_image_renderer_top.v | 202 ++ vga_tester.v | 6 - 19 files changed, 5614 insertions(+), 21 deletions(-) create mode 100644 .gitignore create mode 100755 build_image.rb create mode 100755 double_dabble.rb create mode 100644 double_dabble_counters.bin create mode 100644 double_dabble_counters.v create mode 100644 image_data.txt create mode 100644 image_index_to_color.v create mode 100644 image_ram.v create mode 100644 image_ram_dat.txt create mode 100644 palette_data.txt create mode 100644 pong_runner.bin create mode 100644 vga_image_renderer.bin create mode 100644 vga_image_renderer.v create mode 100644 vga_image_renderer_top.bin create mode 100644 vga_image_renderer_top.v diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..07d2a3f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/test +/test.vcd diff --git a/Makefile b/Makefile index 90bfbdb..8313add 100644 --- a/Makefile +++ b/Makefile @@ -1,19 +1,21 @@ CONSTRAINTS = ../Go_Board_Constraints.pcf -LED_TOGGLE = pong_runner.bin +LED_TOGGLE = double_dabble_counters.bin install: $(LED_TOGGLE) iceprog $(LED_TOGGLE) .PHONY: test test: - iverilog -o test uart_rx_test.v uart_rx.v + iverilog -o test image_index_to_color.v vvp test gtkwave test.vcd .SUFFIXES: .v .json .bitstream .bin .v.json: - yosys -q -p "hierarchy -top PongRunner; synth_ice40 -json $*.json" $*.v vga_sync_pulse_generator.v vga_current_beam_position.v vga_add_porches_to_output.v uart_rx.v uart_tx.v pong.v pong_ball.v pong_paddle.v debounce_filter.v + #yosys -q -p "hierarchy -top VGAImageRenderer_Top; synth_ice40 -json $*.json" $*.v vga_sync_pulse_generator.v vga_current_beam_position.v vga_add_porches_to_output.v image_index_to_color.v image_ram.v + #yosys -q -p "hierarchy -top VGAImageRenderer_Top; synth_ice40 -json $*.json" $*.v vga_image_renderer.v image_ram.v image_index_to_color.v vga_sync_pulse_generator.v vga_current_beam_position.v vga_add_porches_to_output.v + yosys -q -p "hierarchy -top DoubleDabbleCounter_Top; synth_ice40 -json $*.json" $*.v .json.bitstream: #nextpnr-ice40 --hx1k --freq 25 --pcf $(CONSTRAINTS) --json $*.json --package vq100 --asc $*.bitstream diff --git a/build_image.rb b/build_image.rb new file mode 100755 index 0000000..6a2e5a5 --- /dev/null +++ b/build_image.rb @@ -0,0 +1,101 @@ +#!/usr/bin/env ruby + +require 'rmagick' + +class GoBoardPixel + GO_BOARD_CHANNEL_TO_RMAGICK_CHANNEL = 65_536 / 8 + + attr_reader :red, :green, :blue + + def self.from_magick(red:, green:, blue:) + new( + red: red / GO_BOARD_CHANNEL_TO_RMAGICK_CHANNEL, + green: green / GO_BOARD_CHANNEL_TO_RMAGICK_CHANNEL, + blue: blue / GO_BOARD_CHANNEL_TO_RMAGICK_CHANNEL + ) + end + + def initialize(red:, green:, blue:) + @red = red + @green = green + @blue = blue + end + + def distance_from_real_pixel(red:, green:, blue:) + (red - @red * GO_BOARD_CHANNEL_TO_RMAGICK_CHANNEL)**2 + + (green - @green * GO_BOARD_CHANNEL_TO_RMAGICK_CHANNEL)**2 + + (blue - @blue * GO_BOARD_CHANNEL_TO_RMAGICK_CHANNEL)**2 + end + + def distance_from_go_pixel(red:, green:, blue:) + (red - @red)**2 + + (green - @green)**2 + + (blue - @blue)**2 + end + + def eql?(other) + red == other.red && green == other.green && blue == other.blue + end + + def hash + [red, green, blue].hash + end +end + +ImagePixel = Data.define(:red, :green, :blue) + +image = Magick::Image.read(ARGV[0]).first +image.change_geometry!('80x60^') do |cols, rows, img| + img.resize!(cols, rows) +end +image.crop!(Magick::CenterGravity, 80, 60, true) + +possible_colors = {} +image.each_pixel do |px| + go_px = GoBoardPixel.from_magick(red: px.red, green: px.green, blue: px.blue) + possible_colors[go_px] ||= 0 + possible_colors[go_px] += 1 +end + +pixels_by_usage = possible_colors.sort_by(&:last).reverse + +go_board_palette = pixels_by_usage[0..31].map(&:first) +color_mapping = go_board_palette.each_with_index.each_with_object({}) do |(go_px, index), obj| + obj[go_px] = index +end + +pixels_by_usage[32..].map(&:first).each do |go_px| + best_match = go_board_palette.each_with_index.map do |target_go_px, index| + [ + target_go_px.distance_from_go_pixel( + red: go_px.red, + green: go_px.green, + blue: go_px.blue, + ), index + ] + end.sort_by(&:first).first + + color_mapping[go_px] = best_match.last +end + +File.open('image_data.txt', 'w') do |fh| + image.each_pixel do |px| + magick_px = GoBoardPixel.from_magick( + red: px.red, green: px.green, blue: px.blue + ) + + fh.puts format('%05b', color_mapping[magick_px]) + end +end + +File.open('palette_data.txt', 'w') do |fh| + go_board_palette.each do |color| + fh.puts format('%09b', ((color.red << 6) + (color.green << 3) + color.blue)) + end +end + +# [ ] load image +# [ ] downsample to 40x30 +# [ ] change to indexed image with go board palette +# [ ] save out body data +# [ ] save out palette data diff --git a/double_dabble.rb b/double_dabble.rb new file mode 100755 index 0000000..8060803 --- /dev/null +++ b/double_dabble.rb @@ -0,0 +1,37 @@ +#!/usr/bin/env ruby + +# build double dabble in ruby so I can feel how it works + +number = 999 + +puts "Binary: #{number.to_s(2)}" + +binary_registers = number.to_s(2).split('').map(&:to_i) + +scratch_size = 4 * (binary_registers.count / 3).ceil +scratch_space = Array.new(binary_registers.count + scratch_size) { 0 } + +binary_registers.each_with_index do |reg, i| + scratch_space[-(binary_registers.count - i)] = reg +end + +pp (scratch_space.count / 4).to_i + +binary_registers.count.times do + (scratch_size / 4).to_i.times do |j| + value = scratch_space[j * 4..j * 4 + 3].join.to_i(2) + + next unless value > 4 + + value += 3 + + scratch_space[j * 4..j * 4 + 3] = value.to_s(2).split('').map(&:to_i) + end + + (scratch_space.count - 1).times do |j| + scratch_space[j] = scratch_space[j + 1] + end + scratch_space[-1] = 0 + + pp scratch_space +end diff --git a/double_dabble_counters.bin b/double_dabble_counters.bin new file mode 100644 index 0000000000000000000000000000000000000000..22540ba9f2ea2d4d8d8d6485a97ecf4a5ca73962 GIT binary patch literal 32220 zcmeHPUub1V8UN<=f7(W$R;OFHyEA>(Oa=U=&1&=nLL1oc*lYE>3SA?v3my@No62r}q4uk0U97@WIhB zgO>u?VoaOVGhBKq8H|LwEjdIk2gc|dR0NF(*!-kx`3Uw6poIQv%ehlJZh*Pa9FofW#jC^e@E%o5B*;2R`2ijij9N_P*Cf z(}W2~TsuCFSzf<3`WIU8kSi}$B7P&fs62BAUO`OnPb49olmw{ujWm?-Zc2jo{v0(& zIj@u^(eMR?$EYP;R#*hykQWdV^|({LlHzU;QeMWWr90In^j<%U$exE?T4EfSYl~wD zq=2`~^(V_t$NPxUt!C35ot*N)?pjnUV2RFVqfsc@=n8`IHo6A-$+s2m}gRH56c z#l{fS#73%iF9mtYjmPMv&6cVTR%kxTkn|WvgF=(&G4%*O|)lzl6 zam0%&55#G3T-_>BYJ|+?97LQ1zz`yo3Ed*Sj4L#UX4U1&5uWla3%_ZYXDw>_95kdQ}D&u8`UVZf~O_DN0Isoh4bU+KI#?*}Q zdbJQ{9@Ejh5@KY(BMD_O$!2HzeJ_ktUnIWWZelU-Q-A|*Cn#{QHyfn_lWsCSEA@{1 zK)o@(T5cp^6R6Yr9N_3LmSc$~*;FK_+N?>GnL?E}?-4YWU!*`Bi@t|6$`45}P8CwB zItxP`D5QFEOsk2as$VTVx=J*6Jy+K>TtCaDy2$bp`}ffpd+Sqz+JX|9Xwb`}*F-U; zefjj?J}T_~I$IJYzTP-$xtw{aF;X>I;0fhrT?Kw@c4}J9a;_2?;4qe-->C>ubi4pvC{?O&;{C4>8oXI#%o z)nr;yhmCxF5u0e5I>iMk2OfKeJiF`p84W|5ic~dHM&ifHgpr4@3$)Ikdx)Bx!mADB z!~bsi*&D#4nJ>u~G>Yp+s>b#bMlPY3AKrKRR-qxeHRWaXpYNfU@jX}G))1~6shX&v zdsL5ndWv+LK6gS;x1eAW-T&fO7m+fWdyVi|xT@CzSKWj|_0Zq{m{Moz8rLYU8>t!-c#P4oXVl1nncheAoa(Nxq~rkKdFK!4QZz@@RxxA|sP|_QNnlUz zU&OqOS4;#J*fL*0FR6=O$}D6~1J;gHCr(c4r+N$r?#?JffRuL56`Fr7_B%U`OlvtlXIYk{;>Ah{7oBK(+a2Ujy=!G3%mwLk&;bazE-eiHe8X>nH4;;KK_L=%DTKwQNGy7t}SS*9~ikzl*isJ zqg+OY1lY?Dq}dy}h!X1bWE(v3yRU&Lz?fn7AAvVoG)h9b%V(Z~GtkqMOb9m)swX5O zrlK-RCJ$dnAg}&wBE`0-9LI?PpxXyO?WaX3GoCyr>2b;2l=Qs(=Ilf2n#-wbiYxYy zsyYnyI=#f}>(7s#rRP>j;2ckFBPRs{*=ZML4G{pxFo{Yi=@VuZS6#tWKmUr0l9=j^ z;|Jy?rbU^S2m3BeHTr;`cY2AGSfqZJ_osq(sjyV>vnj_}R^sJQwAcT3-8>3NEG;c% zwJK88l))P;9iZHx2LWF8gx}E$Z6fEkFCM;qRDo%CDG>6q+xF9Y#}d&Mq2+t&9c5mO z`ILD`@3BDHB9+uVvrG1y**+=Z**2Tf`q2qLE5r zh|J4!N?*q2DRw(4&EmU-QtEi@ytM76gn4;so|ij4FI%>1^LLL;W83Oe0jj8fgGR%@ z2nE&p*><4x*KoHX&E0o%!s0h)**&sq_J-@qa6?{p<+km5r$b)u>@6Ougs;oF+q^@+N>9S#jlrPT722i}yuRL{;) zmM+~)qH^Shz2utHT&FtPUZ0m5r)#6DJ+xJO2U6y|$8VgMd<%khz{@RoQ*`M<(L~!g zZyVXu137tlw^M8fo@S? z4rF)?bjxN1KZ63DQDBIL^FU{m4Xia+z2fAppf~!G+&L}Vxh4VmXlntywfi6-Y voCmsSvx2KZfzBu}R0-#S&L|sLg92ToKsXO{(Pjl#g94pV;K(!IXFc$L4XAX! literal 0 HcmV?d00001 diff --git a/double_dabble_counters.v b/double_dabble_counters.v new file mode 100644 index 0000000..b2a1841 --- /dev/null +++ b/double_dabble_counters.v @@ -0,0 +1,136 @@ +module DoubleDabbleCounter_Top( + input i_Clk, + + output o_Segment1_A, + output o_Segment1_B, + output o_Segment1_C, + output o_Segment1_D, + output o_Segment1_E, + output o_Segment1_F, + output o_Segment1_G, + output o_Segment2_A, + output o_Segment2_B, + output o_Segment2_C, + output o_Segment2_D, + output o_Segment2_E, + output o_Segment2_F, + output o_Segment2_G +); + reg [6:0] r_currentNumber = 0; + reg [$clog2(10000000)-1:0] r_counter; + + always @(posedge i_Clk) begin + if (r_counter == 10000000) begin + r_counter <= 0; + if (r_currentNumber == 99) begin + r_currentNumber <= 0; + end else begin + r_currentNumber <= r_currentNumber + 1; + end + end else begin + r_counter <= r_counter + 1; + end + end + + wire [8:0] w_binaryCodedNumber; + + wire [3:0] w_decimal1, w_decimal2; + wire [6:0] w_segment1, w_segment2; + + IntegerToBCD integerToBCD ( + .i_BinaryNumber(r_currentNumber), + .o_BinaryCodedDecimal(w_binaryCodedNumber) + ); + + assign w_decimal1 = w_binaryCodedNumber[7:4]; + assign w_decimal2 = w_binaryCodedNumber[3:0]; + + BCDTo7Segment segment1 ( + .i_Clk(i_Clk), + .i_BinaryCodedDecimal(w_decimal1), + .o_SegmentLights(w_segment1) + ); + + BCDTo7Segment segment2 ( + .i_Clk(i_Clk), + .i_BinaryCodedDecimal(w_decimal2), + .o_SegmentLights(w_segment2) + ); + + assign o_Segment1_A = !w_segment1[6]; + assign o_Segment1_B = !w_segment1[5]; + assign o_Segment1_C = !w_segment1[4]; + assign o_Segment1_D = !w_segment1[3]; + assign o_Segment1_E = !w_segment1[2]; + assign o_Segment1_F = !w_segment1[1]; + assign o_Segment1_G = !w_segment1[0]; + + assign o_Segment2_A = !w_segment2[6]; + assign o_Segment2_B = !w_segment2[5]; + assign o_Segment2_C = !w_segment2[4]; + assign o_Segment2_D = !w_segment2[3]; + assign o_Segment2_E = !w_segment2[2]; + assign o_Segment2_F = !w_segment2[1]; + assign o_Segment2_G = !w_segment2[0]; + + // register that goes to 99 + // debounce two input buttons + // button 1 increases + // button 2 decreases + +endmodule + +module BCDTo7Segment( + input i_Clk, + input [3:0] i_BinaryCodedDecimal, + output reg [6:0] o_SegmentLights +); + always @(posedge i_Clk) begin + case (i_BinaryCodedDecimal) + 0: o_SegmentLights <= 7'b1111110; + 1: o_SegmentLights <= 7'b0110000; + 2: o_SegmentLights <= 7'b1101101; + 3: o_SegmentLights <= 7'b1111001; + 4: o_SegmentLights <= 7'b0110011; + 5: o_SegmentLights <= 7'b1011011; + 6: o_SegmentLights <= 7'b1011111; + 7: o_SegmentLights <= 7'b1110000; + 8: o_SegmentLights <= 7'b1111111; + 9: o_SegmentLights <= 7'b1111011; + default: o_SegmentLights <= 7'b0000000; + endcase + end +endmodule + +/** + * From https://github.com/AmeerAbdelhadi/Binary-to-BCD-Converter + * This halts until the conversion is done! + */ +module IntegerToBCD( + input [MAX_BIT_WIDTH-1:0] i_BinaryNumber, + output reg [SCRATCH_AREA_WIDTH:0] o_BinaryCodedDecimal +); + // this is all the go board will need for the 7 segment display to go to 99 + parameter MAX_BIT_WIDTH = 7; + + localparam SCRATCH_AREA_WIDTH = MAX_BIT_WIDTH+(MAX_BIT_WIDTH-4)/3; + + integer i,j; + + always @(i_BinaryNumber) begin + for (i = 0; i <= SCRATCH_AREA_WIDTH; i = i + 1) begin + o_BinaryCodedDecimal[i] = 0; + end + + o_BinaryCodedDecimal[MAX_BIT_WIDTH-1:0] = i_BinaryNumber; + + // this does the shift-and-add in small pieces + for (i = 0; i <= MAX_BIT_WIDTH - 4; i = i + 1) begin + for (j = 0; j <= i / 3; j = j + 1) begin + if (o_BinaryCodedDecimal[MAX_BIT_WIDTH-i+4*j -: 4] > 4) begin + o_BinaryCodedDecimal[MAX_BIT_WIDTH-i+4*j -: 4] = o_BinaryCodedDecimal[MAX_BIT_WIDTH-i+4*j -: 4] + 4'd3; + end + end + end + end +endmodule diff --git a/image_data.txt b/image_data.txt new file mode 100644 index 0000000..94b996b --- /dev/null +++ b/image_data.txt @@ -0,0 +1,4800 @@ +00000 +00000 +00000 +00000 +00000 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00011 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00011 +00011 +00011 +00010 +00010 +00011 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00000 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00011 +00011 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +01101 +10001 +01101 +00000 +00011 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +00010 +00010 +00011 +00010 +01101 +11110 +00100 +11110 +11001 +10001 +01101 +01101 +01101 +01101 +01101 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +00010 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +10001 +00100 +00100 +00101 +00101 +00100 +00100 +00100 +00101 +00101 +00101 +00101 +11110 +10001 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +01101 +01101 +00010 +00010 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +01101 +11110 +00100 +00100 +11001 +00100 +00100 +00100 +00100 +00100 +00100 +00100 +00100 +00101 +00101 +11110 +10001 +01011 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +00010 +01101 +10010 +10010 +11001 +10111 +01001 +10111 +01101 +00010 +01101 +00010 +00010 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +01101 +11110 +00101 +00100 +11110 +11001 +11001 +00100 +00100 +00100 +00100 +00100 +00100 +00100 +00100 +00101 +00101 +00101 +11110 +10001 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00011 +00011 +00011 +00010 +01101 +10010 +10111 +11101 +11101 +11101 +11101 +11101 +01001 +10111 +10111 +10111 +11010 +11001 +00010 +00011 +00011 +00011 +00011 +00011 +00010 +11001 +11110 +00101 +00100 +11001 +11110 +00100 +00100 +00100 +11001 +11001 +00101 +00101 +00101 +00101 +00101 +00101 +00101 +01110 +01110 +01101 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00011 +00011 +01101 +11010 +11101 +11101 +11101 +11101 +11101 +11101 +01001 +01001 +01001 +01001 +01001 +00111 +01100 +10010 +00010 +00011 +00011 +00011 +00010 +11110 +10010 +00100 +00101 +00100 +00100 +00101 +00100 +00100 +11001 +10010 +00100 +00101 +00101 +00101 +00101 +01110 +01110 +01110 +01110 +01110 +00101 +10001 +01101 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00010 +11010 +01001 +11101 +01001 +01001 +11101 +01001 +00111 +00111 +01001 +01001 +01001 +00111 +00111 +00110 +01101 +00001 +00001 +00001 +00010 +00100 +00100 +00101 +00101 +00101 +00101 +00101 +00101 +00101 +00100 +11110 +00101 +00100 +11001 +00100 +00101 +01110 +01110 +01110 +01110 +01110 +01110 +01110 +01110 +11001 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00010 +01100 +00111 +01001 +01001 +11010 +11101 +01001 +00111 +01100 +01001 +01001 +00111 +00111 +00111 +00110 +00100 +00010 +00001 +00001 +00010 +00100 +11000 +00101 +11011 +01010 +01010 +10000 +00100 +00101 +00101 +00101 +00101 +00100 +00100 +00101 +01110 +01110 +11011 +01010 +11000 +01110 +01110 +01110 +11000 +10001 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00010 +10000 +11010 +01001 +11010 +11010 +01001 +00111 +00111 +01010 +01001 +00111 +00111 +11011 +01010 +00110 +00101 +10001 +00010 +00001 +01101 +10000 +00111 +01010 +01010 +00111 +01001 +11101 +01001 +01100 +00100 +00100 +00101 +00101 +00101 +00101 +00101 +01110 +00101 +11000 +00110 +01010 +11000 +11000 +01101 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +10000 +11010 +11101 +11010 +11010 +01001 +00111 +00110 +01100 +01001 +00111 +00111 +11000 +11011 +00110 +00101 +01000 +10001 +00010 +11110 +11000 +00111 +00111 +00110 +00111 +11101 +01001 +01001 +00111 +01100 +00100 +00100 +00101 +00101 +00101 +00101 +01110 +01110 +01110 +00101 +11011 +01010 +00100 +01101 +00010 +00010 +00010 +00000 +00000 +00000 +01101 +01101 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +10010 +01100 +01001 +11010 +11010 +01001 +00111 +00110 +01100 +01001 +00111 +00110 +11000 +11011 +00110 +01110 +10110 +10101 +10001 +11001 +10100 +10111 +00110 +01100 +00111 +11101 +01001 +00111 +00110 +00111 +00100 +00100 +00100 +00101 +00101 +00101 +00101 +01110 +00101 +00100 +00101 +11000 +11011 +01010 +10010 +01101 +11001 +11001 +11001 +10000 +10000 +10000 +11001 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +10100 +10000 +00111 +01100 +01100 +00111 +00111 +00110 +01100 +00111 +00111 +00110 +01110 +11011 +01010 +01110 +10110 +11100 +11110 +10100 +00001 +10100 +00101 +00101 +01100 +01001 +00111 +00110 +00110 +01010 +11000 +00100 +00100 +00101 +00101 +00101 +00101 +01110 +01110 +00100 +00100 +00100 +11000 +00101 +11000 +11011 +01010 +01010 +11011 +11000 +11011 +01010 +00110 +11001 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +01101 +01100 +01100 +01010 +01010 +10000 +01010 +01010 +01100 +00111 +00110 +11000 +01010 +11011 +01110 +10011 +11110 +01100 +10100 +00001 +11001 +11001 +11001 +11010 +01001 +00110 +11011 +11011 +01010 +01100 +00111 +00110 +01010 +00101 +11110 +00101 +01110 +01110 +11000 +10000 +10000 +10000 +00100 +00100 +00100 +00100 +00100 +10000 +01010 +01010 +00100 +01010 +11110 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +10100 +00100 +00110 +00111 +00111 +00111 +11010 +01100 +00110 +01010 +11000 +00110 +11000 +10011 +10011 +01100 +11101 +10100 +10100 +10100 +11001 +11001 +11010 +11010 +11011 +00100 +00101 +11110 +00100 +10111 +10000 +01010 +00110 +00101 +00101 +01110 +01110 +01110 +00101 +00100 +01010 +10000 +10000 +01010 +01010 +01010 +01010 +11001 +01101 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +10100 +01100 +00111 +00111 +00111 +00111 +00111 +00111 +00110 +00110 +00110 +01110 +10011 +00101 +00111 +01111 +10010 +10010 +00100 +00100 +10010 +10111 +10000 +00101 +11001 +11001 +00011 +01101 +00001 +10010 +00110 +00110 +01110 +01110 +01110 +01110 +01110 +00101 +01101 +01101 +11001 +11001 +00100 +11001 +10001 +01101 +00000 +00011 +00011 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +10000 +00110 +00110 +00110 +00110 +00110 +00110 +00110 +00110 +11000 +11110 +10011 +00101 +01001 +10100 +01110 +00100 +10100 +00100 +00100 +00100 +00100 +00100 +11001 +11001 +00001 +00001 +00001 +10111 +00111 +00110 +01110 +01110 +01110 +01110 +01110 +11110 +01101 +00010 +00011 +00010 +00010 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +01101 +00100 +00100 +11001 +11001 +00100 +01010 +11011 +11000 +11001 +00001 +00010 +11110 +01001 +10010 +01110 +10010 +01111 +10010 +00100 +00100 +11110 +00100 +10111 +10010 +10100 +00001 +10100 +10111 +00111 +00110 +01110 +01110 +01110 +10011 +01000 +10001 +00000 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +01101 +00010 +00001 +00001 +00001 +01101 +11010 +10100 +11110 +10111 +10100 +10010 +01111 +01111 +01111 +01111 +01111 +10100 +10100 +10100 +10100 +10100 +11101 +00110 +00101 +10011 +10011 +10110 +10110 +01000 +01000 +11100 +11100 +11100 +11100 +11100 +11100 +10001 +10001 +01101 +00000 +00010 +00010 +00010 +00000 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +10010 +01111 +10100 +10010 +10010 +10000 +01111 +01111 +01111 +01111 +10100 +10100 +10111 +00101 +01110 +10010 +01111 +00111 +11000 +10011 +10011 +10011 +10011 +10011 +10011 +10011 +10110 +01000 +01000 +01000 +01000 +01000 +01000 +01000 +01000 +11100 +10001 +10001 +10001 +00010 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +10100 +10111 +10100 +10100 +10100 +10100 +10111 +01111 +01111 +10100 +10111 +10111 +01010 +01110 +01110 +00100 +11101 +00111 +00110 +11011 +00101 +10011 +10011 +10011 +10011 +10011 +10011 +10011 +10110 +10110 +01000 +01000 +01000 +01000 +10110 +10110 +10011 +01000 +01101 +00011 +00010 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +11001 +10100 +01111 +10100 +10100 +10010 +10010 +10010 +10111 +10111 +10000 +01110 +01110 +00101 +10111 +01001 +00110 +00110 +11011 +11110 +01000 +10011 +10110 +01000 +01000 +01000 +01000 +01000 +01000 +01000 +01000 +01000 +01000 +01000 +10001 +10001 +00000 +00010 +00010 +00010 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +10100 +01111 +01111 +10100 +10100 +10100 +10100 +10100 +10100 +10010 +00100 +10010 +10100 +01001 +01100 +00110 +11000 +10001 +01011 +01011 +10101 +01000 +01000 +01000 +01000 +01000 +01000 +01000 +01000 +10011 +01000 +01101 +00010 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +10010 +10100 +01111 +01111 +01111 +01111 +01111 +01111 +01111 +01111 +01111 +01001 +01100 +11011 +00101 +10001 +11111 +00000 +00000 +11111 +10101 +01000 +10011 +10011 +10011 +10011 +10011 +10011 +10001 +00000 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +11110 +00100 +00100 +10000 +10111 +01111 +01111 +10100 +10111 +10000 +00100 +00101 +10011 +01000 +01011 +00000 +00000 +00000 +00000 +11111 +10101 +01000 +01000 +01000 +01000 +10001 +01101 +00010 +00010 +00010 +00010 +00010 +00011 +00010 +00010 +00011 +00011 +00011 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +01011 +10001 +01000 +00101 +10111 +01111 +10100 +00100 +01110 +10011 +01000 +01000 +11100 +01011 +01011 +01011 +11111 +00000 +00000 +00000 +11111 +01011 +11110 +11000 +00101 +11110 +00000 +00011 +00010 +00010 +00011 +00011 +01101 +11001 +01101 +00010 +01101 +01101 +00010 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +01101 +00000 +00000 +11110 +00100 +10111 +00100 +00101 +10011 +10101 +10101 +01011 +01011 +11111 +01011 +01011 +01011 +01011 +11111 +00000 +00000 +11111 +10001 +11000 +11000 +11110 +00010 +00011 +00010 +01101 +01101 +11001 +00100 +10000 +01010 +10000 +01100 +10000 +10001 +00000 +00000 +00000 +00000 +00000 +01011 +01011 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +01101 +00000 +00010 +10001 +00101 +00101 +00101 +10001 +00000 +00000 +11111 +11111 +11111 +11111 +10101 +11100 +10101 +01011 +01011 +11111 +00000 +00000 +11111 +10001 +11110 +01101 +00000 +00010 +10100 +01001 +11010 +11010 +11010 +01010 +01010 +01010 +01100 +01010 +00100 +00000 +00000 +00000 +00000 +00000 +01011 +01011 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +10001 +11001 +01100 +01100 +10000 +00100 +11001 +00010 +00010 +00000 +00000 +11111 +11111 +11111 +01011 +10101 +11100 +11100 +01011 +01011 +11111 +01011 +01011 +01011 +11100 +01000 +01000 +01000 +01000 +10000 +00110 +01100 +00111 +00111 +01100 +00110 +00110 +11000 +10001 +00010 +00010 +00000 +00000 +00000 +01101 +01011 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +11001 +11011 +00110 +10100 +00001 +10100 +01100 +10010 +00010 +00010 +00000 +00000 +01011 +01011 +01011 +01011 +10001 +01000 +01000 +10001 +01011 +00000 +00000 +01011 +01011 +01000 +01000 +01000 +01000 +01000 +11110 +10001 +00100 +00110 +00110 +11011 +11000 +11001 +00010 +00010 +00000 +00000 +00000 +00000 +01011 +10001 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +10010 +11001 +10100 +10000 +01111 +01100 +00110 +10010 +00010 +00010 +00000 +01011 +01011 +01011 +10001 +00100 +10000 +10000 +10000 +11110 +10001 +01011 +01011 +10101 +10110 +11100 +10101 +10101 +10101 +10101 +10101 +11100 +11000 +11000 +00100 +01101 +00000 +00010 +00010 +00000 +00000 +00000 +00000 +00000 +01011 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +11001 +11000 +10010 +10100 +11011 +11011 +00010 +00010 +00000 +01011 +01011 +10101 +11001 +11010 +10000 +11010 +00110 +01100 +11000 +11100 +10101 +10110 +10110 +10101 +10101 +10101 +10101 +10101 +11100 +01000 +11001 +01101 +00010 +00011 +00010 +00010 +00010 +00010 +00000 +00000 +00000 +01101 +10001 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +10100 +11000 +00100 +11011 +00110 +00000 +00000 +11111 +01011 +01011 +10101 +10000 +11010 +01100 +01100 +11011 +00111 +11000 +10011 +10110 +10110 +11100 +10101 +10101 +11100 +11100 +10110 +01000 +01101 +00010 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00000 +00000 +01011 +10001 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +11000 +11000 +11000 +10001 +10101 +10101 +01011 +01011 +10101 +00100 +00111 +00111 +00111 +00110 +00100 +00101 +10011 +10110 +10101 +10101 +11100 +10110 +10110 +10110 +10001 +00000 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00000 +00000 +00000 +01101 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00100 +11011 +11000 +10001 +10101 +01011 +01011 +01011 +01011 +10001 +11110 +00100 +00100 +11110 +01000 +10110 +10110 +10110 +11100 +11100 +10110 +01000 +10001 +00000 +00010 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00000 +01101 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00010 +10001 +01011 +01011 +01011 +01011 +01011 +01011 +01011 +01011 +10101 +10101 +11100 +11100 +11100 +10011 +10011 +10110 +10110 +01000 +10001 +00010 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +01101 +01101 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +01101 +01011 +01011 +01011 +01011 +01011 +01011 +10101 +10101 +11100 +11100 +11100 +01000 +10011 +10110 +10110 +01000 +01101 +00010 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00000 +01101 +00000 +00000 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00010 +01101 +10001 +10101 +10101 +10101 +11100 +10110 +10110 +10110 +10110 +10011 +10011 +01000 +01101 +00010 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +01101 +01101 +00010 +00010 +00000 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00010 +01101 +10001 +10001 +10001 +01000 +01000 +10001 +10001 +01101 +00010 +00001 +00011 +00011 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00000 +00010 +00010 +00010 +00000 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00011 +00011 +00010 +00010 +00010 +00010 +00000 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00010 +00011 +00011 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +00010 +00010 +00010 +00010 +00010 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +00010 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +00010 +00010 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +00010 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +00010 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00010 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00011 +00011 +00011 +00011 +00011 +00010 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00001 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 +00011 diff --git a/image_index_to_color.v b/image_index_to_color.v new file mode 100644 index 0000000..a4ae9a3 --- /dev/null +++ b/image_index_to_color.v @@ -0,0 +1,94 @@ +module ImageIndexToColor( + input i_Clk, + + input [4:0] i_ColorIndex, + + input i_DoWrite, + input [3:0] i_WriteColorIndex, + input [2:0] i_WriteColor_Red, + input [2:0] i_WriteColor_Green, + input [2:0] i_WriteColor_Blue, + + output [2:0] o_Red, + output [2:0] o_Green, + output [2:0] o_Blue, + + output reg o_WriteComplete +); + reg [8:0] r_colors[0:31]; + + initial begin + $readmemb("palette_data.txt", r_colors); + end + + always @(posedge i_Clk) begin + if (i_DoWrite) begin + r_colors[i_WriteColorIndex] <= { + i_WriteColor_Red, i_WriteColor_Green, i_WriteColor_Blue + }; + o_WriteComplete <= i_DoWrite; + end + end + + assign o_Red = r_colors[i_ColorIndex][8:6]; + assign o_Green = r_colors[i_ColorIndex][5:3]; + assign o_Blue = r_colors[i_ColorIndex][2:0]; +endmodule + +module TestImageIndexToColor(); + reg i_Clk = 0; + + always #2 i_Clk <= !i_Clk; + + reg [3:0] r_colorIndex = 0; + wire [2:0] w_Red, w_Green, w_Blue; + wire w_writeComplete; + + reg r_doWrite = 0; + reg [2:0] r_WriteColor_Red = 3'b111; + reg [2:0] r_WriteColor_Green = 3'b000; + reg [2:0] r_WriteColor_Blue = 3'b001; + reg [3:0] r_writeColorIndex = 0; + + ImageIndexToColor ii2c ( + .i_Clk(i_Clk), + + .i_ColorIndex(r_colorIndex), + + .i_DoWrite(r_doWrite), + .i_WriteColorIndex(r_writeColorIndex), + .i_WriteColor_Red(r_WriteColor_Red), + .i_WriteColor_Green(r_WriteColor_Green), + .i_WriteColor_Blue(r_WriteColor_Blue), + + .o_Red(w_Red), + .o_Green(w_Green), + .o_Blue(w_Blue), + .o_WriteComplete(w_writeComplete) + ); + + initial begin + $dumpfile("test.vcd"); + $dumpvars; + + #2; + #2; + + r_colorIndex = 1; + + #2; + #2; + + r_doWrite = 1; + + #2; + #2; + + r_colorIndex = 15; + + #2; + #2; + + $finish; + end +endmodule diff --git a/image_ram.v b/image_ram.v new file mode 100644 index 0000000..637be10 --- /dev/null +++ b/image_ram.v @@ -0,0 +1,92 @@ +module ImageRAM( + input i_Clk, + + input i_doRead, + input [$clog2(WIDTH)-1:0] i_ReadX, + input [$clog2(HEIGHT)-1:0] i_ReadY, + + input [$clog2(WIDTH)-1:0] i_WriteX, + input [$clog2(HEIGHT)-1:0] i_WriteY, + input [$clog2(INDEXES)-1:0] i_WriteData, + input i_DoWrite, + + output reg o_ReadDataReady, + output reg [4:0] o_ReadData, + + output reg o_WriteComplete +); + parameter INDEXES = 8; + parameter WIDTH = 80; + parameter HEIGHT = 60; + + reg [4:0] r_Memory[0:HEIGHT-1][0:WIDTH-1]; + + initial begin + $readmemb("image_data.txt", r_Memory); + end + + // reading + always @(posedge i_Clk) begin + o_ReadData <= r_Memory[i_ReadY][i_ReadX]; + o_ReadDataReady <= i_doRead; + end + + // writing + always @(posedge i_Clk) begin + if (i_DoWrite) begin + r_Memory[i_WriteY][i_WriteX] <= i_WriteData; + o_WriteComplete <= i_DoWrite; + end + end +endmodule + +module TestImageRAM(); + reg r_Clk = 0; + always #2 r_Clk <= !r_Clk; + + reg r_doRead = 0; + + reg [5:0] r_readX = 0; + reg [4:0] r_readY = 0; + + wire w_readDataReady; + wire [2:0] w_readData; + + ImageRAM MyRam ( + .i_Clk(r_Clk), + .i_doRead(r_doRead), + .i_ReadX(r_readX), + .i_ReadY(r_readY), + .o_ReadDataReady(w_readDataReady), + .o_ReadData(w_readData) + ); + + initial begin + $dumpfile("test.vcd"); + $dumpvars; + + #2; + #2; + + r_doRead <= 1; + + #2; + #2; + + r_doRead <= 0; + r_readX <= 1; + r_readY <= 0; + + #2; + #2; + + r_doRead <= 1; + + #2; + #2; + + r_doRead <= 0; + + $finish; + end +endmodule diff --git a/image_ram_dat.txt b/image_ram_dat.txt new file mode 100644 index 0000000..634ecb8 --- /dev/null +++ b/image_ram_dat.txt @@ -0,0 +1,2 @@ +011 +101 diff --git a/palette_data.txt b/palette_data.txt new file mode 100644 index 0000000..62bc2b9 --- /dev/null +++ b/palette_data.txt @@ -0,0 +1,32 @@ +011110111 +101111111 +100110111 +100111111 +100011011 +011010010 +110011010 +111100011 +001011100 +111100100 +101011010 +010101111 +110011011 +011101110 +010001001 +111101101 +101011011 +010100101 +101100100 +000010011 +110101101 +001100110 +000011100 +110100100 +100010010 +100100100 +110100011 +101010010 +001100101 +111101100 +011011011 +010110111 diff --git a/pong_runner.bin b/pong_runner.bin new file mode 100644 index 0000000000000000000000000000000000000000..3c2ef3ed96ed880c220445f252505e2e163327d7 GIT binary patch literal 32220 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 literal 0 HcmV?d00001 diff --git a/vga_add_porches_to_output.v b/vga_add_porches_to_output.v index c85f270..7b47b3c 100644 --- a/vga_add_porches_to_output.v +++ b/vga_add_porches_to_output.v @@ -1,6 +1,9 @@ /** * The output is buffered as the front/back porches are added, so watch your * timing for other stuff. +* +* Side effects: +* * Blanks o_ if within HSync/VSync */ module VGA_Add_Porches_To_Output( input i_Clk, @@ -55,21 +58,23 @@ module VGA_Add_Porches_To_Output( .o_Y(w_Y) ); + wire w_withinHPorch, w_withinVPorch, w_withinSync; + + assign w_withinHPorch = (w_X < FRONT_PORCH_COUNT_X + ACTIVE_COLUMNS) || + (w_X > TOTAL_COLUMNS - BACK_PORCH_COUNT_X - 1); + assign w_withinVPorch = (w_Y < FRONT_PORCH_COUNT_Y + ACTIVE_ROWS) || + (w_Y > TOTAL_ROWS - BACK_PORCH_COUNT_Y - 1); + assign w_withinSync = (w_X > ACTIVE_COLUMNS) || (w_Y > ACTIVE_COLUMNS); + // https://web.mit.edu/6.111/www/s2004/NEWKIT/vga.shtml always @(posedge i_Clk) begin - if ( - (w_X < FRONT_PORCH_COUNT_X + ACTIVE_COLUMNS) || - (w_X > TOTAL_COLUMNS - BACK_PORCH_COUNT_X - 1) - ) begin + if (w_withinHPorch) begin o_HSync <= 1; end else begin o_HSync <= w_HSync; end - if ( - (w_Y < FRONT_PORCH_COUNT_Y + ACTIVE_ROWS) || - (w_Y > TOTAL_ROWS - BACK_PORCH_COUNT_Y - 1) - ) begin + if (w_withinVPorch) begin o_VSync <= 1; end else begin o_VSync <= w_VSync; @@ -84,8 +89,15 @@ module VGA_Add_Porches_To_Output( r_Green <= i_Green; r_Blue <= i_Blue; - o_Red <= r_Red; - o_Green <= r_Green; - o_Blue <= r_Blue; + // Ensure we never deliver color data during hsync/vsync + if (w_withinSync) begin + o_Red <= 0; + o_Green <= 0; + o_Blue <= 0; + end else begin + o_Red <= r_Red; + o_Green <= r_Green; + o_Blue <= r_Blue; + end end endmodule diff --git a/vga_current_beam_position.v b/vga_current_beam_position.v index f203e5c..c29eed8 100644 --- a/vga_current_beam_position.v +++ b/vga_current_beam_position.v @@ -10,11 +10,16 @@ module VGA_Current_Beam_Position( output reg o_VSync = 0, output reg [$clog2(TOTAL_COLUMNS)-1:0] o_X, - output reg [$clog2(TOTAL_ROWS)-1:0] o_Y + output reg [$clog2(TOTAL_ROWS)-1:0] o_Y, + + output o_IsActiveArea ); parameter TOTAL_COLUMNS = 800; parameter TOTAL_ROWS = 525; + parameter ACTIVE_COLUMNS = 640; + parameter ACTIVE_ROWS = 480; + wire w_frameStart; // forward these flip-flop style. use these instead of what @@ -44,4 +49,5 @@ module VGA_Current_Beam_Position( // rising vsync == new frame assign w_frameStart = (~o_VSync & i_VSync); + assign o_IsActiveArea = (o_X < ACTIVE_COLUMNS && o_Y < ACTIVE_COLUMNS); endmodule diff --git a/vga_image_renderer.bin b/vga_image_renderer.bin new file mode 100644 index 0000000000000000000000000000000000000000..1e5db8c1807b391e488c657857bf170fff1ca6f5 GIT binary patch literal 32220 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 UK@xHo@(2tz0((yVH7LXX0id^b00000 literal 0 HcmV?d00001 diff --git a/vga_image_renderer.v b/vga_image_renderer.v new file mode 100644 index 0000000..2430745 --- /dev/null +++ b/vga_image_renderer.v @@ -0,0 +1,81 @@ +module VGAImageRenderer( + input i_Clk, + input i_HSync, + input i_VSync, + + output o_HSync, + output o_VSync, + output [2:0] o_Red, + output [2:0] o_Green, + output [2:0] o_Blue +); + // sync signals + wire w_HSync_FromCurrentPos, w_VSync_FromCurrentPos; + wire w_IsActiveArea; + + // screen location + wire [9:0] w_X, w_Y; + wire [6:0] w_CellX; + wire [5:0] w_CellY; + + // ram reading + reg r_doImageRAMRead = 1; + reg r_doImageRAMWrite = 0; + wire w_imageRAMReadDataReady; + wire [4:0] w_imageRAMReadData; + + wire [2:0] w_Red, w_Green, w_Blue; + + VGA_Current_Beam_Position currentPos ( + .i_Clk(i_Clk), + .i_HSync(i_HSync), + .i_VSync(i_VSync), + + .o_HSync(w_HSync_FromCurrentPos), + .o_VSync(w_VSync_FromCurrentPos), + .o_X(w_X), + .o_Y(w_Y), + .o_IsActiveArea(w_IsActiveArea) + ); + + assign w_CellX = w_X[9:3]; + assign w_CellY = w_Y[9:3]; + + // takes a tick, so add one to HSync/VSync + ImageRAM imageRam ( + .i_Clk(i_Clk), + .i_ReadX(w_CellX), + .i_ReadY(w_CellY), + .i_doRead(r_doImageRAMRead), + .o_ReadDataReady(w_imageRAMReadDataReady), + .o_ReadData(w_imageRAMReadData), + + .i_WriteX(), + .i_WriteY(), + .i_WriteData(), + .i_DoWrite(r_doImageRAMWrite), + .o_WriteComplete() + ); + + ImageIndexToColor palette ( + .i_Clk(i_Clk), + .i_ColorIndex(w_imageRAMReadData), + .o_Red(w_Red), + .o_Green(w_Green), + .o_Blue(w_Blue), + + .i_DoWrite(r_doImageRAMWrite), + .i_WriteColorIndex(), + .i_WriteColor_Red(), + .i_WriteColor_Green(), + .i_WriteColor_Blue(), + .o_WriteComplete() + ); + + assign o_Red = w_IsActiveArea ? w_Red : 0; + assign o_Green = w_IsActiveArea ? w_Green : 0; + assign o_Blue = w_IsActiveArea ? w_Blue : 0; + + assign o_HSync = w_HSync_FromCurrentPos; + assign o_VSync = w_VSync_FromCurrentPos; +endmodule diff --git a/vga_image_renderer_top.bin b/vga_image_renderer_top.bin new file mode 100644 index 0000000000000000000000000000000000000000..3d20d3f233fae977b32611cdef438c26a974f975 GIT binary patch literal 32220 zcmeHw4R~Btx$d`rW->{WcBh1rVl69m2q{(^+E6Rjx+YB^EeO+|A_WA7T53elqJ@Ka z<*uYHv=uQFJO-?uEl=Q7#A8L#>fs!x{CEma5%ke>>wQpT1w}<~{XJauUhn&@pP47lrWa69HfYXYKznBj5B8=t4Ao= zYDcSOs+5Oaj;6Daa#{^HDV04!iM>{qEW1Hz8BK!|Cc%?=>@ZEQs$nYPVRH#HT$D;J zxpp=MB&M~7P1s5uVUA*C+r`$;YMR-BRfQ$}R#uvu!5P^)s=yZN02!5y>9=53pkNCh z2VThsgx{jhI6Jy#Yg+ryy;b6&7 z_d1zsou?p2E*nQGPRX=+sb*Bl6~*8JBPZJ#E?46LV{S&@6&-F0$c-bAa-?2Z|Fe zlX62M;3De@owLQXqo55MXm;IilT&D|ytxcs}VAzi^DV0YJoYMEl4hxskfh2$f zC;!*bf@Tjd(4#aOw>XX=HA|72wc(r?svw#X=$`DeDGf$F3jEtKOaH+SvXAIs!+pyr z6loeeYz%IY8LuIXaJHC!m>BswrKIvD!*&=}k`EcU{@zcrCCJk0Ww~(&E@v2?_rf0I zjCTH93KM2WX%y@y9Oy~^(;3C4cJIaz34>2y=$3lAOHK?)yz8fTOQZTl30w*hZgVNU zeu2IPc9*E<6W`3>76jQFl-YtEh$N*YwsfLb;L3%R^Dp=(E}qgA974(r`T7uOyIX)! zqNfC9gx@>s%Sf)eXtvU~2I-4SFX%ut={dUo-ub~;6Ll8%0U8<30<0p-64bIxuVJZB zTE7$*;Aa+(V1#_XcC2_3=5#48r$lLR=*BzKo5$ctU9=S`ai@{VEaLHX&9*7|C@4gR z_RyxKSf6=k#)4>w_fJk4T>Eq)C{_I$SDFo?J0-z8EGKBw%a7MBv&A=DB_SBE(z(JpR4 zN~hd#!k%(1_3}j2e*NY#)N-I*@0SYI;fWKy9x0il2s~g0)O|YTu^LW%$HgiA;+f@? zUQrHn`q|e9VD*Z)l7+WYY}>Z+}xpV&bW$f5TCTdY-pFtiC5R zgA8?$;FK}vr;&yio&YO)mCcPLJ2GapxLhy^<&imi2={)vC(?Iu96pY605_Hz4q;IK zhBaf(;J8VtyTPQ0rWeVNJ1@U9Q%=dD8S=v=W%z($ilWoUFt>2M ztWBu{gbCx%Q+JGnMa;A)ok^k}NFN$}jrjZDaM^@yh# z5GCwd6bZuu9q6g7OI-2Ao-8Y|mVDKy-oh8v#bNs*wwNo6+kV+n9$xfi*@kKL4E~U7 zSfO;XmO&|?RXhA}5Bvk|aU}{;S2D11Deiu~mh2V|=}w{1RbvhJlrwwEOU4!o26aj? za9yl*+l0Z&c9Aqd-rl`Mk-z*Qy}wj^ZHa@MTDJSWJW85TLL=~JNhA(!;Mqyt}K) zK-8kJJb?`FsLF_$x%ud8u!mk|;z9B5sth=)xUurSYffb9#}|Uvr?) zMxI*J>Na%YIHhgvFhW`?&_QYoHagw;Gt@Sd4P#vLF6=OziDpSe(5kBrW zP|M&~hjI^RMG55CaIG)FLX}^aWyg(XJ927WMLI**5EL=ZSl2?id@2 z8BQN|M~lJ!29epS zT@`IFujl)Um%shrV^{=MrDQz8xrUe9HgScZ68&<9F0XX8bQmkgL3rIWXj<+#W(!#C z4Y-ua5G}WPXEQI{eI?p9$rI`%g;$BOg{OP6Q*(j$_W#3JDZ8Z;IA3w7VaXr zsja2^S}}PSo|NrPK6k9HC0pvJ)Sk&Te-$ZfaH(e|%>0yQ|6yF}EJC*i_GPHQWLzF4 zr8&+dS~ZCn9rBWKse21^7^Ru3WeqO1?+Caw-Ce6#C~-3xvMG-qs*dh{Dc=7ZDP5`T z@n398ezZFQDdQJ)!s^-hDb+-zOn{sy&iRECCg2MG1EmRq*xiJ`%%c9IM{aTM=8|+` zU2Y$K5S|_GuML22`*qdE5>D)=ORCyPc-l3Cc~qKE|Jt(t~`KFcpBBE z3C)O}e%@7Uj%Z`9#+G>Up73}oSneil&7xR-rdxquufjo&A{!9<`d!T6L2 zDkK7}I8WK9#R(U`RWy#~RvwyGe3;2+pRcG!vJd*I%y=%}^!vEV1SQo!{-LSB!_+<1 z&{7B;#$Pqz%Z;XmVU-;Zpu4=Py16bNqc)7Sicl$0WzdTEp7P5y&UsmJe9DNT4|Q)r zMChVOdOg`cmOP{5aks!jd44dO@yr)XT`sbjMA};q4Hst2_Xl_!HH*S>F@LxHbx7&LMSowX%jQ)}?@ii<38@@k` z2%*q0>F-P!m#cZ=$ybot=D%4XqkT@D=GRTJI7DAIwG3zcN+&>*es&bktyj@S5(-|g zIe<+A+eW)xae2332Pl2=|HAhaOVrOc3BF-AUug;2+hQg@i$}(!sOP&oi@wmWD)4!U zFF4QvU(#KBJ4Q*t?>zy=`(^jK3%9#3=3`iRd6@R_EulBYqD9izmMM*)zVDcZQIky5Y))`t`Y6rJS5C%~XiJbMaWtOz zDXSI19!Bc(%$hNrX_bhC z)YV{=Ha~M6z*ErUPHrtO)=R=IkRF1^>cCARKENm=ObP>;g*#Q;<=c`>s}`j-;}!0elePe11=s}ig$vV zEoOT^9tF-2U?|!T*#wgyumQplr#zFH=1>TM*c=>@sG#-~hiQiC-)}roA0_AD* zXj^&E#>_3wFMRQT#=a5hY(evEdl_^V&4WK8kKc4w@(q|1V?KLqk;~EgJ#G@Y_5yBl{f{^=FZ12xfh~9*Ec-`5(FHefqu;DLp#%18l5EI3eHuLkprSeZ0AL#LaD^ z-+b`um~(hN3a`8V{7IZj<8TR+ApcFD`!odeLbyLm4l1qHHYw>Jd&%0Tw3z`g^PYdN z4Iz@oG;Q%P#YF#{mT84oGl~Uwl{0P(YQL5w{YuX@bL;|6=?{IDM_HGqP3Lj>wE1g5 zir0MrN*xjy!LP5|I7ZRTvzDS-bj^dIwP8ZEmpSx{;ptJHo4mL5c78aW6j%0hV1#$x6t-PhhwmcTW2-ACo#uZMg5p@4q5`cfE>yQ-U81!urZfzO^1T zIc|W@=!m*;wSQtjv_WENGj~=Fi(GW7uW;uy|zmqp}?oG zfCVIVi&wUI^YM>6$5W`~)(sCKB}k1+i7ELCDR2KRr~L4jFi4`0U(c;0sf9fGr6Q#H zXL}fBqxdEITGDp`=~S~qvkh0M=AX7gp-fQC5#P3S3YV^R_yAiZu3)P zHMr!2pvY_aNd~J7%5uZIU=1$W%=eckzgF4vAG6b!;TjO>@epnFZ@U7&Pv%bkN`wLg zs_rO>#I^s8VYvB=-{Mg&m946NN=dK&Iw?&2_1#$v59eq-5b+Vo|I%an(B^Y+!*^7x zHtR;}*0?3@y`WGsqf{8>X`h}^2Sm2-&ke^rzBs^lG_tHmYVK01Xzd=BaV~_EdD9Q{ zr+gc!S&UX<%HAap@F#^06bj53AO90zlW_1kj+c>v(f03VFv`Zi2Yy2_BTFsGP>y5@ zR6yd=M|Yr8&rNLbcmH7Tp7FTkQ*$HD`o$_9rS}dV<*_{<{CM3@G!hZZzM;?_XjqH_ zHRO&z$f>I-)c2RP=N*_-Zuy(?Jqj3lHZ|^@Jb~e3e)u_rXUxZp>;h)9kh6G9C4F~fj{~tcrE-7{3HX6VQoLlR~waFhU;j^M&V&S7#U@wi9=ZH73=09SB z;|LCcD*o-GcdDM?K*T?%Xvm#IeBpyVNdccLbo^U!_D8{K+S6R3W|@q!GTWwg|8^Vp zngcU=zBqdnSSf6~_DIpr{Zrj21ft%&enf)J%|{{#7*Vblo|hXp4j?ulxi zJH)nEbjt&fW*&$n7A;pHx+GPHDiy#$S#Yt&0l0xz)iX z`y;w_KYh;jLmj&@MsqZ4a}3vUeBj^?H!#L#ZId1on99D!+)h2q7`!qkJ{peF6 zUa$s*WDk_=7K~lv+?@TI3iaG=Bndh!KoI~rQ6I649aS$EI30T`39!tY?rdjIjZ+dp+Dlo_uy_^&Z4IG zDii088D4I2H4GkPZQ!ioTP65jRzNiss|@bD^A>~ZtK7PuaMzvT+@ zwbS1QwQ`%I71!`@us}^pGAnNZinTJ~MvkAr@bL=6#_A%mU$zGIpRSj?zw8COi3px( zQYKPts+3i0lWLM_lJb8b<)n@~6*N_WsR~S0;Llb8cj5T69pGq*#nGHE3!i#f%;GOF zi78zE1&aQn4;h*s`nEPH6G`nE_pxH)BP7!#<^M-gT3jYamXu%0D3vKnGEGvhq|Atk z%V#2#VaYT}IgxU*8Of%cINshKPaNn{CP%i#bkl$uKT2V|ikaZ1=JvaM=yJ*|KJS{q znv}+vXr*u|6UKyCPTB3YCOigUQc|-zQ0GTzn#{QD2%NF}88uQ}LCIPt8fB$(eW^Uk zdC~<;l(HP?IykP3;8My3(s^o9mdoz^sAYXp#_Uqk68m|V;t5lR`tvT?uK0e#l5&FO zOI}r~vlMWS8)b+WZ)!RlRT)+uWzNCOJ*<#A0B=p2KnEOUcRjW$?XpmDaYTLEteZ5w zdg-&}hj|tIcu9CyOEum+-V)Ml&&C(;lcIHv-kwPWauM+4eX?Yiu@df1mWo9$;p9`Q zIMMY;qFt(5x2QEtS{L{R?Sv1-6UXBLl%V2V8k;bb|2fH5RvzUYB|fB$-cyesC7|L8 z>6AHfMLminyl;%rSm`Jc{N-dfPRMZKmyQ-y@rj`8?22{-Nu5-(p7;n6Wpl5Uj)+*ew@4K4yxKbsuY`nM|aG~V+H%#MNM9-DqOsl znt3!rt|3v;3tBV=BUgM$shbsrmIvNa^H)_xrk0vaa>T8f#{$#y{-mjFaDx<%=1BNCejmB;gq^N|>tRH;#{~ zSSC?u4nESil$AtI!hY$*qi`jU;EZbQN8WxE(K>q5dkC)-4B-oj+OH03@=U2y6_~2P z%ew+YcqwUW8+duI@zm_5DlkC>TD__JfeA`9<({g*%fA9s_X98gHJ+N`R0SreK&!9s z2Yft-JN6{mjwfL9yrLXozDUZEA%!1uwSdQX=-49LhhmQwr(`rFJnHmh#6QjL^!AV3 zgu(y#MIhnav8fKnaGw&-WZ)1H&`@P_)Xh-{vcpdPS zw0q?Pzg8Z(wThPBT+SYsD0)FFpTW@E``iLA&DQXOUzwVY6 z=D#Z4_ZsFSo3gNPpBeo&yA^fZNyTgmS!eKYv#)9dn#q7=mZ|`hRp^7xJdQ^~Gkk=WqCzVlU$^ zbKnqo##4`sdcd2Xc_hnx<`q9;d^FB1ZOCo~59Ym#@tN_L6mQYETNyT=h<^UUbq0^r z%ecz;y)&89(AHa+ZyOq!!Cd)$J=xd5zAe9+@#e?p=QJ1Bd@7xhKGLPt!JKTZKpm#ndc4fk6YUrmau2&rmW07vntcOH7lFPR%K{V$T_2{GTv}3M{ik` ziBv3$D+`UR(-~63vA}#VmLYQza`iF;yECt4Kgoux%P`b%{Ctk#OY;52eHwn(U-no= z5y|T>TcPlO0FZC{xpXjO*va%(1H;v40-o^y%^JWDa159e;IzCyq8RXM01UhEv!1k! z{B8I};hO#J46|9Zznx)r=6USnIId{j zq2aiK*3C4q^rL%5@uLgCl;POoJ$HN-yxBVxbpn>m)0jxVS6awC(^p#9^9b`p3&XqE zzyJPGpQy2~aK%`f=*@ldNB5io-Fxd7*KI+Zcf%L&`B#SBt~rPL!2R3XIz5HA;eWSm z-J{Th|I&63>;BSihHJ*}?!FJO%J_>HGt4r6IMcwfH_h9k@;`ndZ=2gUFJIaTJ{TCEqmBaPGPHv@-#g8row zI`~}P{=nyqwq|-C9+myTALHJ z@{gEpaP_16M}RY#9yItnF6!6Y;+YPAUVo&3pYv1wQ4DiY5A%ep0Dw{ILGtZ%Q#QR8pDOv z$8l->QkZy2ljNa}^ZHYo&o3GNNon|}j=;B?&?EhqcHTQ;${?0MO zgD%561}wkA@VD81N8+B1Uw*QQ_nNBtnWuyueEf8?;k~CDzUE}Z`<5BrV7YJo(sDmz z{PTZf`R#_EXYGAw8@<=!sMq49*WzoV#nVQMr}d$U-(>Y#+&TO?`!zP-IQ&_>I@}41 zzY{G#)#6YTvU>g<4sTX>_A+;VhqoFI{AygB=x|rYnZsLs-cgIcyv1YQ;H^U*i5uK? zSlk^6mkyucMP6sGWN_!Wy&r&Eu-kFKTkH9Z;T=W8j|8(?`*I7*TJBlcIv!Y91{Q9! zEbqP2z@RW-xPxJ#26klq=gl#3`L|lW#_;p{4exdQVxt%OEVppG+`{u}3&-^qewSN) zQ>%%0@Y`hjm0@V%w)hMa=Xkg6FKqm&7Jeei8rWGb9K4PMza!aeV2JHc=RMKE&%x1g zXRqNMdCK$pS9oZ2Ia!{v@s{UnbU99!`gqc_95)uA4taF`s+GnMym=fy5eNP_jDWW) z4%}(I!b6=e$QYg+v-AmK|0jIE3 AM*si- literal 0 HcmV?d00001 diff --git a/vga_image_renderer_top.v b/vga_image_renderer_top.v new file mode 100644 index 0000000..fbe08c6 --- /dev/null +++ b/vga_image_renderer_top.v @@ -0,0 +1,202 @@ +module VGAImageRenderer_Top( + input i_Clk, + + output o_VGA_HSync, + output o_VGA_VSync, + output o_VGA_Red_0, + output o_VGA_Red_1, + output o_VGA_Red_2, + output o_VGA_Grn_0, + output o_VGA_Grn_1, + output o_VGA_Grn_2, + output o_VGA_Blu_0, + output o_VGA_Blu_1, + output o_VGA_Blu_2 +); + localparam TOTAL_COLUMNS = 800; + localparam TOTAL_ROWS = 525; + + localparam ACTIVE_COLUMNS = 640; + localparam ACTIVE_ROWS = 480; + + localparam VIDEO_WIDTH = 3; + + wire w_HSync_FromPulseGenerator, w_VSync_FromPulseGenerator; + wire w_HSync_FromImageRenderer, w_VSync_FromImageRenderer; + wire w_HSync_FromPorchSync, w_VSync_FromPorchSync; + + wire [2:0] w_Red_FromImageRenderer, w_Green_FromImageRenderer, w_Blue_FromImageRenderer; + wire [2:0] w_Red_FromPorchSync, w_Green_FromPorchSync, w_Blue_FromPorchSync; + + VGA_Sync_Pulse_Generator #( + .TOTAL_COLUMNS(TOTAL_COLUMNS), + .TOTAL_ROWS(TOTAL_ROWS), + .ACTIVE_COLUMNS(ACTIVE_COLUMNS), + .ACTIVE_ROWS(ACTIVE_ROWS) + ) pulseGenerator ( + .i_Clk(i_Clk), + + .o_HSync(w_HSync_FromPulseGenerator), + .o_VSync(w_VSync_FromPulseGenerator), + + .o_rawX(), + .o_rawX() + ); + + VGAImageRenderer imageRenderer ( + .i_Clk(i_Clk), + + .i_HSync(w_HSync_FromPulseGenerator), + .i_VSync(w_VSync_FromPulseGenerator), + + .o_HSync(w_HSync_FromImageRenderer), + .o_VSync(w_VSync_FromImageRenderer), + .o_Red(w_Red_FromImageRenderer), + .o_Green(w_Green_FromImageRenderer), + .o_Blue(w_Blue_FromImageRenderer) + ); + + wire w_HSync_FromImageDimmer, w_VSync_FromImageDimmer; + wire [2:0] w_Red_FromImageDimmer, w_Green_FromImageDimmer, w_Blue_FromImageDimmer; + + ImageMovingSpotlight imageDimmer ( + .i_Clk(i_Clk), + + .i_HSync(w_HSync_FromImageRenderer), + .i_VSync(w_VSync_FromImageRenderer), + .i_Red(w_Red_FromImageRenderer), + .i_Green(w_Green_FromImageRenderer), + .i_Blue(w_Blue_FromImageRenderer), + + .o_HSync(w_HSync_FromImageDimmer), + .o_VSync(w_VSync_FromImageDimmer), + .o_Red(w_Red_FromImageDimmer), + .o_Green(w_Green_FromImageDimmer), + .o_Blue(w_Blue_FromImageDimmer) + ); + + VGA_Add_Porches_To_Output #( + .VIDEO_WIDTH(VIDEO_WIDTH), + .TOTAL_COLUMNS(TOTAL_COLUMNS), + .TOTAL_ROWS(TOTAL_ROWS), + .ACTIVE_COLUMNS(ACTIVE_COLUMNS), + .ACTIVE_ROWS(ACTIVE_ROWS) + ) PorchOutput ( + .i_Clk(i_Clk), + + .i_HSync(w_HSync_FromImageDimmer), + .i_VSync(w_VSync_FromImageDimmer), + .i_Red(w_Red_FromImageDimmer), + .i_Green(w_Green_FromImageDimmer), + .i_Blue(w_Blue_FromImageDimmer), + + .o_HSync(w_HSync_FromPorchSync), + .o_VSync(w_VSync_FromPorchSync), + .o_Red(w_Red_FromPorchSync), + .o_Green(w_Green_FromPorchSync), + .o_Blue(w_Blue_FromPorchSync) + ); + + assign o_VGA_HSync = w_HSync_FromPorchSync; + assign o_VGA_VSync = w_VSync_FromPorchSync; + + assign o_VGA_Red_0 = w_Red_FromPorchSync[0]; + assign o_VGA_Red_1 = w_Red_FromPorchSync[1]; + assign o_VGA_Red_2 = w_Red_FromPorchSync[2]; + + assign o_VGA_Grn_0 = w_Green_FromPorchSync[0]; + assign o_VGA_Grn_1 = w_Green_FromPorchSync[1]; + assign o_VGA_Grn_2 = w_Green_FromPorchSync[2]; + + assign o_VGA_Blu_0 = w_Blue_FromPorchSync[0]; + assign o_VGA_Blu_1 = w_Blue_FromPorchSync[1]; + assign o_VGA_Blu_2 = w_Blue_FromPorchSync[2]; +endmodule + +module ImageMovingSpotlight( + input i_Clk, + input i_HSync, + input i_VSync, + input [2:0] i_Red, + input [2:0] i_Green, + input [2:0] i_Blue, + + output reg o_HSync, + output reg o_VSync, + output reg [2:0] o_Red, + output reg [2:0] o_Green, + output reg [2:0] o_Blue +); + parameter VIDEO_WIDTH = 3; + parameter TOTAL_COLUMNS = 800; + parameter TOTAL_ROWS = 525; + + wire w_HSync, w_VSync; + + wire [$clog2(TOTAL_COLUMNS)-1:0] w_X; + wire [$clog2(TOTAL_ROWS)-1:0] w_Y; + reg [$clog2(12500000)-1:0] r_counter = 0; + + reg [VIDEO_WIDTH-1:0] r_Red = 0; + reg [VIDEO_WIDTH-1:0] r_Green = 0; + reg [VIDEO_WIDTH-1:0] r_Blue = 0; + + reg [$clog2(TOTAL_COLUMNS)-1:0] r_currentX = 4; + reg [$clog2(TOTAL_ROWS)-1:0] r_currentY = 3; + + VGA_Current_Beam_Position #( + .TOTAL_COLUMNS(TOTAL_COLUMNS), + .TOTAL_ROWS(TOTAL_ROWS) + ) CurrentPosition ( + .i_Clk(i_Clk), + .i_HSync(i_HSync), + .i_VSync(i_VSync), + .o_HSync(w_HSync), + .o_VSync(w_VSync), + .o_X(w_X), + .o_Y(w_Y) + ); + + wire [6:0] w_CellX; + wire [5:0] w_CellY; + + assign w_CellX = w_X[9:3]; + assign w_CellY = w_Y[9:3]; + + always @(posedge i_Clk) begin + if (r_counter == 25000000/16) begin + r_counter <= 0; + + if (r_currentX == 80 - 1) begin + r_currentX <= 0; + end else begin + r_currentX <= r_currentX + 1; + end + end else begin + r_counter <= r_counter + 1; + end + end + + always @(posedge i_Clk) begin + o_HSync <= w_HSync; + o_VSync <= w_VSync; + + // if the pointer is right on the square, white + // if the pointer is within a square, brighten by {[0, 1], 1} + // otherwise return the current red + + o_Red <= r_Red; + o_Green <= r_Green; + o_Blue <= r_Blue; + + r_Red <= (r_currentX == w_CellX && r_currentY == w_CellY) ? 7 : i_Red; + r_Green <= (r_currentX == w_CellX && r_currentY == w_CellY) ? 7 : i_Green; + r_Blue <= (r_currentX == w_CellX && r_currentY == w_CellY) ? 7 : i_Blue; + /* + (r_currentX > 0 && w_X == r_currentX - 1 && r_currentY == w_Y) ? {i_Red[0:1], 1} : + (r_currentX < TOTAL_COLUMNS - 2 && w_X == r_currentX + 1 && r_currentY == w_Y) ? {i_Red[0:1], 1} : + (r_currentY > 0 && w_Y == r_currentY - 1 && r_currentX == w_X) ? {i_Red[0:1], 1} : + (r_currentY < TOTAL_ROWS - 2 && w_Y == r_currentY + 1 && r_currentX == w_X) ? {i_Red[0:1], 1} : i_Red; + */ + end +endmodule diff --git a/vga_tester.v b/vga_tester.v index 7c57da2..a45657c 100644 --- a/vga_tester.v +++ b/vga_tester.v @@ -168,12 +168,6 @@ module VGA_Tester( .i_HSync(w_HSync_Start), .i_VSync(w_VSync_Start), - .o_HSync(w_HSync_FromTestPattern), - .i_Clk(i_Clk), - .i_Pattern(r_currentPattern), - .i_HSync(w_HSync_Start), - .i_VSync(w_VSync_Start), - .o_HSync(w_HSync_FromTestPattern), .o_VSync(w_VSync_FromTestPattern), .o_Red(w_Red_FromTestPattern),