module vga_sq(input wire clk,reset,
output wire hsync,vsync,
output [2:0] red, // three bit signal to drive color red
output [2:0] green, // three bit signal to drive color green
output [1:0] blue, // two bit signal to drive color blue (human eye is less sensitive to color blue)
output reg video_on);
// defining constants
localparam HD = 800; // horizontal display area
localparam HF = 56; // front porch (right border)
localparam HB = 64; //right porch (left border)
localparam HR = 120; // horizontal retrace
localparam VD = 600; // vertical display area
localparam VF = 37; // front porch (bottom border)
localparam VB = 23; // back porch (top border)
localparam VR = 6; // vertical retrace
localparam h_end = 1040; // total horizontal timing
localparam v_end = 666; // total vertical timing
//localparam sq_size = 20; // size of square
localparam sq_x_l = 390; // left coordinate of square
localparam sq_x_r = 410;
localparam sq_y_t = 290;
localparam sq_y_b = 400;
//horizontal and vertical counter
reg [10:0] h_count_reg,v_count_reg ; // registers for sequential horizontal and vertical counters
reg[10:0] h_count_next , v_count_next;
//reg v_sync_reg , h_sync_reg ;
//wire v_sync_next , h_sync_next ;
reg v_sync_next , h_sync_next = 0 ;
always @ ( posedge clk , posedge reset)
if (reset)
begin
v_count_reg <= 0;
h_count_reg <= 0 ;
//v_sync_reg <= 1'b0;
//h_sync_reg <= 1'b0;
end
else
begin
v_count_reg <= v_count_next;
h_count_reg <= h_count_next;
//v_sync_reg <= v_sync_next ;
//h_sync_reg <= h_sync_next ;
end
// horizontal and vertical counters
always @(posedge clk)
begin
if(h_count_next < h_end-1)
begin
h_count_next <= h_count_next + 1;
end
else
begin
h_count_next <= 0;
if(v_count_next < v_end-1)
v_count_next <= v_count_next + 1;
else
v_count_next <= 0;
end
end
// horizontal and vertical synchronization signals
always @(posedge clk)
if(h_count_reg < HR)
h_sync_next <= 1;
else
h_sync_next <= 0;
//VSync logic
always @(posedge clk)
if(v_count_reg < VR)
v_sync_next <= 1;
else
v_sync_next <= 0;
assign hsync = h_sync_next;
assign vsync = v_sync_next;
reg h_video_on,v_video_on; // these registers ensure that the display signals are sent only when the pixels are within the display region of the monitor.
//horizontal logic
always @(posedge clk)
if((h_count_reg >= HR + HF) && (h_count_reg< HR + HF + HD))
h_video_on <= 1;
else
h_video_on <= 0;
//Vertical logic
always @(posedge clk)
if((v_count_reg >= VR + VF) && (v_count_reg < VR + VF+ VD))
v_video_on <= 1;
else
v_video_on <= 0;
always @(posedge clk)
if(h_video_on && v_video_on)
video_on <= 1;
else
video_on <= 0;
reg [9:0] pixel_x,pixel_y; // registers to describe current position of pixel within display area.
always @(posedge clk)
if(h_video_on)
pixel_x <= h_count_reg - HR - HF;
else
pixel_x <= 0;
always @(posedge clk)
if(v_video_on)
pixel_y <= v_count_reg - VR - VF;
else
pixel_y <= 0;
//color output
reg [7:0] coloroutput; // 8 bit register which describes which color has to be displayed but only when video_on signal is turned on.
always @(posedge clk)
if(~video_on)
coloroutput <= 0;
else
begin
if((pixel_x > sq_x_l && pixel_x < sq_x_r) && (pixel_y > sq_y_t && pixel_y < sq_y_b ))
coloroutput[7:5] <= 3'b111;
else
coloroutput [4:0] <= 5'b00000;
end
assign red = coloroutput[7:5];
assign green = coloroutput[4:2] ;
assign blue = coloroutput[1:0] ;
endmodule
Code Verilog - [expand] 1 2 3 4 if((pixel_x > sq_x_l && pixel_x < sq_x_r) && (pixel_y > sq_y_t && pixel_y < sq_y_b )) coloroutput[7:5] <= 3'b111; else coloroutput [4:0] <= 5'b00000;
Code Verilog - [expand] 1 2 3 4 5 6 7 8 9 instead of code tags in the future? code sorta works, but syntax tags makes it much more readable. Pretty colors AND it helps you in getting your indentation right. [COLOR="silver"][SIZE=1]- - - Updated - - -[/SIZE][/COLOR] I'll put it another way: [I]"As I wish a red colored square, therefore, I assigned these 3 MSBs as 1. "[/I] And what do you do with the other 5 bits at that point in time? If you don't think it is important at that point in time, what hardware do you think the synthesizer is going to infer for you?
Code Verilog - [expand] 1 2 3 4 5 6 7 8 9 10 always @(posedge clk) if(~video_on) coloroutput <= 0; else begin if((pixel_x > sq_x_l && pixel_x < sq_x_r) && (pixel_y > sq_y_t && pixel_y < sq_y_b )) coloroutput[7:5] <= 3'b111; else coloroutput[7:0] <= 8'b00000000; end
Code Verilog - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 module vga_bar(input wire clk,reset, input [1:0] btn, output wire hsync,vsync, output [2:0] red, // three bit signal to drive color red output [2:0] green, // three bit signal to drive color green output [1:0] blue, // two bit signal to drive color blue (human eye is less sensitive to color blue) output reg video_on); // defining constants localparam HD = 800; // horizontal display area localparam HF = 56; // front porch (right border) localparam HB = 64; //right porch (left border) localparam HR = 120; // horizontal retrace localparam VD = 600; // vertical display area localparam VF = 37; // front porch (bottom border) localparam VB = 23; // back porch (top border) localparam VR = 6; // vertical retrace localparam h_end = 1040; // total horizontal timing localparam v_end = 666; // total vertical timing localparam BAR_X_L = 600; localparam BAR_X_R = 603; localparam BAR_Y_SIZE = 72; localparam BAR_V = 4; //bar moving size localparam MAX_Y = 600; //horizontal and vertical counter reg [10:0] h_count_reg,v_count_reg ; // registers for sequential horizontal and vertical counters reg[10:0] h_count_next , v_count_next; //reg v_sync_reg , h_sync_reg ; //wire v_sync_next , h_sync_next ; reg v_sync_next , h_sync_next = 0 ; always @ ( posedge clk , posedge reset) if (reset) begin v_count_reg <= 0; h_count_reg <= 0 ; //v_sync_reg <= 1'b0; //h_sync_reg <= 1'b0; end else begin v_count_reg <= v_count_next; h_count_reg <= h_count_next; //v_sync_reg <= v_sync_next ; //h_sync_reg <= h_sync_next ; end // horizontal and vertical counters always @(posedge clk) begin if(h_count_next < h_end-1) begin h_count_next <= h_count_next + 1; end else begin h_count_next <= 0; if(v_count_next < v_end-1) v_count_next <= v_count_next + 1; else v_count_next <= 0; end end // horizontal and vertical synchronization signals always @(posedge clk) if(h_count_reg < HR) h_sync_next <= 1; else h_sync_next <= 0; //VSync logic always @(posedge clk) if(v_count_reg < VR) v_sync_next <= 1; else v_sync_next <= 0; assign hsync = h_sync_next; assign vsync = v_sync_next; reg h_video_on,v_video_on; // these registers ensure that the display signals are sent only when the pixels are within the display region of the monitor. //horizontal logic always @(posedge clk) if((h_count_reg >= HR + HF) && (h_count_reg< HR + HF + HD)) h_video_on <= 1; else h_video_on <= 0; //Vertical logic always @(posedge clk) if((v_count_reg >= VR + VF) && (v_count_reg < VR + VF+ VD)) v_video_on <= 1; else v_video_on <= 0; always @(posedge clk) if(h_video_on && v_video_on) video_on <= 1; else video_on <= 0; reg [9:0] pixel_x,pixel_y; // registers to describe current position of pixel within display area. always @(posedge clk) if(h_video_on) pixel_x <= h_count_reg - HR - HF; else pixel_x <= 0; always @(posedge clk) if(v_video_on) pixel_y <= v_count_reg - VR - VF; else pixel_y <= 0; //BAR TOP , BOTTOM BOUNDARY wire [10:0] bar_y_t , bar_y_b; //regisers to track top boundary (x position is fixed) reg [10:0] bar_y_reg , bar_y_next; always @(posedge clk , posedge reset) if(reset) begin bar_y_reg <= 0; end else bar_y_reg <= bar_y_next; wire refr_tick; assign refr_tick = ((pixel_y == 601) && (pixel_x == 0)); assign bar_y_t = bar_y_reg; assign bar_y_b = bar_y_t + BAR_Y_SIZE - 1; //pixel within bar wire bar_on; assign bar_on = ((BAR_X_L <= pixel_x) && (pixel_x <= BAR_X_R) && (bar_y_t <= pixel_y) && (pixel_y <= bar_y_b)); wire [2:0] bar_rgb; assign bar_rgb = 3'b111; //new bar y-position always @(*) begin bar_y_next = bar_y_reg; // no move if(refr_tick) if(btn[1] & (bar_y_b < (MAX_Y - 1 - BAR_V))) bar_y_next = bar_y_reg + BAR_V; // move down else if( btn[0] & (bar_y_t > BAR_V)) bar_y_next = bar_y_reg - BAR_V; //move up end //color output reg [7:0] coloroutput; // 8 bit register which describes which color has to be displayed but only when video_on signal is turned on. always @(posedge clk) if(~video_on) coloroutput <= 0; else begin if(bar_on) coloroutput[4:2] <= bar_rgb; else coloroutput[7:0] <= 8'b00000000; end assign red = coloroutput[7:5]; assign green = coloroutput[4:2] ; assign blue = coloroutput[1:0] ; endmodule
entity MyVGA_BouncingBall is
port ( CLK_50MHz: in std_logic;
VS: out std_logic;
HS: out std_logic;
RED: out std_logic_vector(2 downto 0);
GREEN: out std_logic_vector(2 downto 0);
BLUE: out std_logic_vector(2 downto 1);
RESET: in std_logic;
SQUAREWIDTH: in std_logic_vector(7 downto 0)
);
end MyVGA_BouncingBall;
architecture Behavioral of MyVGA_BouncingBall is
-- VGA Definitions starts
constant HDisplayArea: integer:= 800; -- horizontal display area
constant HLimit: integer:= 1040; -- maximum horizontal amount (limit)
constant HFrontPorch: integer:= 56; -- h. front porch
constant HBackPorch: integer:= 64; -- h. back porch
constant HSyncWidth: integer:= 120; -- h. pulse width
constant VDisplayArea: integer:= 600; -- vertical display area
constant VLimit: integer:= 666; -- maximum vertical amount (limit)
constant VFrontPorch: integer:= 37; -- v. front porch
constant VBackPorch: integer:= 23; -- v. back porch
constant VSyncWidth: integer:= 6; -- v. pulse width
signal HBlank, VBlank, Blank: std_logic := '0';
signal CurrentHPos: std_logic_vector(10 downto 0) := (others => '0'); -- goes to 10000010000 = 1040
signal CurrentVPos: std_logic_vector(10 downto 0) := (others => '0'); -- goes to 1010011010= 666
signal ScanlineX, ScanlineY: std_logic_vector(10 downto 0); --pixel_x,pixel_y
signal ColorOutput: std_logic_vector(7 downto 0);
-- VGA Definitions end
signal SquareX: std_logic_vector(9 downto 0) := "0111000101"; -- 453
signal SquareY: std_logic_vector(9 downto 0) := "0001100010"; --98
signal SquareXMoveDir, SquareYMoveDir: std_logic := '0'; --initialized to zero
--signal SquareWidth: std_logic_vector(6 downto 0) := "0011110";
constant SquareXmin: std_logic_vector(9 downto 0) := "0000000001";
signal SquareXmax: std_logic_vector(9 downto 0) := "1100100000"-SquareWidth;
constant SquareYmin: std_logic_vector(9 downto 0) := "0000000001";
signal SquareYmax: std_logic_vector(9 downto 0) := "1001011000"-SquareWidth;
signal ColorSelect: std_logic_vector(2 downto 0) := "001";
signal Prescaler: std_logic_vector(30 downto 0) := (others => '0');
signal Prescaler2: std_logic_vector(30 downto 0) := (others => '0');
begin
PrescalerCounter: process(CLK_50Mhz, RESET)
begin
if RESET = '1' then
Prescaler <= (others => '0');
SquareX <= "0111000101";
SquareY <= "0001100010";
SquareXMoveDir <= '0';
SquareYMoveDir <= '0';
ColorSelect <= "001";
elsif rising_edge(CLK_50Mhz) then
Prescaler <= Prescaler + 1;
if Prescaler = "11000011010100000" then -- Activated every 0,002 sec (2 msec)
if SquareXMoveDir = '0' then
if SquareX < SquareXmax then
SquareX <= SquareX + 1;
else
SquareXMoveDir <= '1';
ColorSelect <= ColorSelect(1 downto 0) & ColorSelect(2);
end if;
else
if SquareX > SquareXmin then
SquareX <= SquareX - 1;
else
SquareXMoveDir <= '0';
ColorSelect <= ColorSelect(1 downto 0) & ColorSelect(2);
end if;
end if;
if SquareYMoveDir = '0' then
if SquareY < SquareYmax then
SquareY <= SquareY + 1;
else
SquareYMoveDir <= '1';
ColorSelect <= ColorSelect(1 downto 0) & ColorSelect(2);
end if;
else
if SquareY > SquareYmin then
SquareY <= SquareY - 1;
else
SquareYMoveDir <= '0';
ColorSelect <= ColorSelect(1 downto 0) & ColorSelect(2);
end if;
end if;
Prescaler <= (others => '0');
end if;
end if;
end process PrescalerCounter;
VGAPosition: process (CLK_50MHz, RESET)
begin
if RESET = '1' then
CurrentHPos <= (others => '0');
CurrentVPos <= (others => '0');
elsif rising_edge(CLK_50MHz) then
if CurrentHPos < HLimit-1 then
CurrentHPos <= CurrentHPos + 1;
else
if CurrentVPos < VLimit-1 then
CurrentVPos <= CurrentVPos + 1;
else
CurrentVPos <= (others => '0'); -- reset Vertical Position
end if;
CurrentHPos <= (others => '0'); -- reset Horizontal Position
end if;
end if;
end process VGAPosition;
-- Timing definition for HSync, VSync and Blank (http://tinyvga.com/vga-timing/640x480@60Hz)
HS <= '0' when CurrentHPos < HSyncWidth else
'1';
VS <= '0' when CurrentVPos < VSyncWidth else
'1';
HBlank <= '0' when (CurrentHPos >= HSyncWidth + HFrontPorch) and (CurrentHPos < HSyncWidth + HFrontPorch + HDisplayArea) else
'1';
VBlank <= '0' when (CurrentVPos >= VSyncWidth + VFrontPorch) and (CurrentVPos < VSyncWidth + VFrontPorch + VDisplayArea) else
'1';
Blank <= '1' when HBlank = '1' or VBlank = '1' else
'0';
ScanlineX <= CurrentHPos - HSyncWidth - HFrontPorch when Blank = '0' else
(others => '0');
ScanlineY <= CurrentVPos - VSyncWidth - VFrontPorch when Blank = '0' else
(others => '0');
RED <= ColorOutput(7 downto 5) when Blank = '0' else
"000";
GREEN <= ColorOutput(4 downto 2) when Blank = '0' else
"000";
BLUE <= ColorOutput(1 downto 0) when Blank = '0' else
"00";
ColorOutput <= "11100000" when ColorSelect(0) = '1' AND ScanlineX >= SquareX AND ScanlineY >= SquareY AND ScanlineX < SquareX+SquareWidth AND ScanlineY < SquareY+SquareWidth else
"00011100" when ColorSelect(1) = '1' AND ScanlineX >= SquareX AND ScanlineY >= SquareY AND ScanlineX < SquareX+SquareWidth AND ScanlineY < SquareY+SquareWidth else
"00000011" when ColorSelect(2) = '1' AND ScanlineX >= SquareX AND ScanlineY >= SquareY AND ScanlineX < SquareX+SquareWidth AND ScanlineY < SquareY+SquareWidth else
"11111111";
SquareXmax <= "1100100000"-SquareWidth;
SquareYmax <= "1001011000"-SquareWidth;
end Behavioral;
reg [10:0] x_location_reg,y_location_reg;
reg [10:0] next_x_location , next_y_location;
@(posedge clk,posedge reset)
if(reset)
x_location_reg <= 0; // registers to store the current position
y_location_reg <= 0;
else
x_location_reg <= next_x_location;
y_location_reg <= next_y_location;
// counter to count upto 100000 to get time delay of 2ms
reg [18:0] tick_tock;
wire click;
always @(posedge clk,posedge reset)
begin
if(reset)
tick_tock <= 0;
else
tick_tock < = tick_tock +1;
end
assign click = (tick_tock == 100000)?1'b1 : 1'b0; //click every 2ms
always @(posedge click or posedge reset)
begin
if(reset)
next_x_location <= 0;
else
next_x_location <= next_x_location +1;
end
always @(posedge click or posedge reset)
begin
if(reset)
next_y_location <= 0;
else
next_y_location <= next_y_location +1;
end
always @(posedge clk , posedge reset)
if((pixel_x >= x_location_reg && pixel_x <= x_location_reg + 5 ) && (pixel_y>= y_location_reg && pixel_y <= y_location_reg + 5 ))
box_on <= 1'b1;
else
box_on <= 1'b0;
Well I am familiar with cloack enables.
Prescaler = "11000011010100000"
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?