## Tuxcon 2018 videos are now online If you missed this event now you can watch all presentations and workshop in TuxCon Youtube channel.

## FPGA tutorial – VGA video Generation with FPGA and Verilog – add video memory to the project and object animation The previous blog about video generation is here.
For the weekend I posted Verilog Programming challenge to change the shape of the square to circle but unfortunately we didn’t got single solution 🙂

I guess you guys also learn yet and this was hard challenge to solve 🙂

In this post I will show you that this is not so hard.

```Let's see again the source from the older post, here is where square is generated:

if(c_col > l_sq_pos_x && c_col < r_sq_pos_x && c_row > u_sq_pos_y && c_row < d_sq_pos_y) begin
//generate blue square
vga_r_r <= 0;
vga_g_r <= 0;
vga_b_r <= 7;
end```

What this codes does? If the video coordinates are within square we assign some color to VGA output.

This is the part we should modify to draw circle but how?

We will use for this purpose video memory and in this memory we will draw circle then when the video beam is in this area it will draw the content of the video memory.

Let’s define the memory:

`   reg [19:0] sq_figure [0:19];`

This defines 20 registers which are 20 bit wide, so we define 20×20 bit video memory which we will use to draw image on the VGA screen.

We also need two counters which to count XY beam position within the square area where we will draw:

```wire [4:0] sq_fig_x;
wire [4:0] sq_fig_y;

assign sq_fig_x = c_col - l_sq_pos_x; // our figure's x axis when in square boundary
assign sq_fig_y = c_row - u_sq_pos_y; // our figure's y axis when in square boundary```

This video memory registers must be load with the ball image, we will do this during the reset state where we initialize other registers too:

```if(reset == 1) begin //while RESET is high init counters
sq_figure[19:0] <= 20'b00000000000000000000;
sq_figure[19:0] <= 20'b00000001111100000000;
sq_figure[19:0] <= 20'b00000111111111000000;
sq_figure[19:0] <= 20'b00011111111111110000;
sq_figure[19:0] <= 20'b00111111111111111000;
sq_figure[19:0] <= 20'b00111111111111111000;
sq_figure[19:0] <= 20'b01111111111111111100;
sq_figure[19:0] <= 20'b01111111111111111100;
sq_figure[19:0] <= 20'b11111111111111111110;
sq_figure[19:0] <= 20'b11111111111111111110;
sq_figure[19:0] <= 20'b11111111111111111110;
sq_figure[19:0] <= 20'b11111111111111111110;
sq_figure[19:0] <= 20'b11111111111111111110;
sq_figure[19:0] <= 20'b01111111111111111100;
sq_figure[19:0] <= 20'b01111111111111111100;
sq_figure[19:0] <= 20'b00111111111111111000;
sq_figure[19:0] <= 20'b00111111111111111000;
sq_figure[19:0] <= 20'b00011111111111110000;
sq_figure[19:0] <= 20'b00000111111111000000;
sq_figure[19:0] <= 20'b00000001111100000000;

c_hor <= 0;
c_ver <= 0;
vga_hs_r <= 1;
vga_vs_r <= 0;
c_row <= 0;
c_col <= 0;
end```

Now we have loaded our video memory with the image of the ball and we should add code which draw it:

```if(c_col > l_sq_pos_x && c_col < r_sq_pos_x && c_row > u_sq_pos_y && c_row < d_sq_pos_y) begin
//generate picture from the video memory
if(sq_figure[sq_fig_y][sq_fig_x] == 1) begin
vga_r_r <= 7;
vga_g_r <= 0;
vga_b_r <= 7;
end
else begin
vga_r_r <= 0;
vga_g_r <= 0;
vga_b_r <= 0;
end```

What we do here? If the video memory is 1 we draw pink dot otherwise black on the screen. Is it really so simple? Let’s compile and see what happens!

Wow it works! You see the picture above.

Let’s copy this code it to example_4.v for further reference.

Now when we have video memory we can change it content and make animations by change dynamically the image inside the video memory.

To do this we have to load the registers with different ‘picture’.

Before we do this first let’s fix something annoying with the keyboard handling which bothers me. When I press up key ball start to move up and I can’t change the direction until it hits the wall.

This is because we commented the code for key release, so the arrow flags are clear press key flag is to hit the wall.

Let’s make this modification:

```if(c_row == 1 && c_col == 1) begin //once per video frame
if(u_arr) begin
if (sq_pos_y > square_size) begin
sq_pos_y <= sq_pos_y - 1;
end
else begin
u_arr <= 0;
d_arr <= 1;
end
end;

if(d_arr) begin
if (sq_pos_y < (v_pixels - 1 - square_size)) begin
sq_pos_y <= sq_pos_y + 1;
end
else begin
d_arr <= 0;
u_arr <= 1;
end
end;

if(l_arr) begin
if (sq_pos_x > square_size) begin
sq_pos_x <= sq_pos_x - 1;
end
else begin
l_arr <= 0;
r_arr <= 1;
end
end;

if(r_arr) begin
if (sq_pos_x < (h_pixels - 1 - square_size)) begin
sq_pos_x <= sq_pos_x + 1;
end
else begin
r_arr <= 0;
l_arr <= 1;
end
end;

end```

Great! Now I can change up down left right direction on the fly while ball is moving, but the ball after a while start moving only diagonally because up down do not change left right direction 🙂
Let’s save current example to example_5.v for further reference and try to modify one more time the code.

Let’s make if ball is moving up but also in any of X direction pressing second time up to make it move stright up and same for other keys.

First we will need to add de-bounce time as once we press the key each frame this means 25 per second key will be scanned .

`reg [19:0] arr_timer; // delay between key check`

We define 20 bit counter, which will be clocked at 25Mhz and will overflow after 0.041(6) seconds, we will check keys only when this counter oveflow:

```arr_timer <= arr_timer + 1;

if(arr_timer == 0) begin
if(ps2_data_reg_prev == 8'he0) begin //0xE0 means key pressed
if(ps2_data_reg == 8'h75) begin
if(u_arr == 1) begin
u_arr <= 1; //0x75 up key
d_arr <= 0;
l_arr <= 0;
r_arr <= 0;
end
else begin
u_arr <= 1; //0x75 up key
d_arr <= 0;
end
ps2_data_reg <= 0;
end
if(ps2_data_reg == 8'h6b) begin
if(l_arr == 1) begin
l_arr <= 1; //0x6B left key
r_arr <= 0;
u_arr <= 0;
d_arr <= 0;
end
else begin
l_arr <= 1; //0x6B left key
r_arr <= 0;
end
ps2_data_reg <= 0;
end
if(ps2_data_reg == 8'h72) begin
if(d_arr == 1) begin
d_arr <= 1; //0x72 down key
u_arr <= 0;
l_arr <= 0;
r_arr <= 0;
end
else begin
d_arr <= 1; //0x72 down key
u_arr <= 0;
end
ps2_data_reg <= 0;
end
if(ps2_data_reg == 8'h74) begin
if(r_arr == 1) begin
r_arr <= 1; //0x74 right key
l_arr <= 0;
u_arr <= 0;
d_arr <= 0;
end
else begin
r_arr <= 1; //0x74 right key
l_arr <= 0;
end
ps2_data_reg <= 0;
end
end
end```

When u_arr is 0 and it is set 1 we just clear d_arr, but if u_arr already has been 1 and we set u_arr again we clear l_arr and r_arr too.

This way if ball moves diagonally up and we press the up key again it will go straight up, same for the other directions too.

Now everything is perfect! Let save it as example_6.v

One last mod: Let’s use arr_timer to dynamically change the video memory, we add this code

```if(arr_timer == 0) begin
sq_figure[19:0] <= sq_figure[19:0] ^ 20'b00000001111000000000;
sq_figure[19:0] <= sq_figure[19:0] ^ 20'b00000001111000000000;
sq_figure[19:0] <= sq_figure[19:0] ^ 20'b00000001111000000000;
sq_figure[19:0] <= sq_figure[19:0] ^ 20'b00000001111000000000;```

What we do here, each time arr_timer overflow (25 000 000 / 2^20) i.e. each 0.0416 seconds we xor few lines of the video memory and thus make square hole inside the ball.

We compile and see that the ball animation works but too fast. Let’s change the arr_timer to 21 bit and slow town the blinking.

The new code is saved as example_7.v What we learn so far? How to define memory in Verilog and how to display this memory content at given coordinates.

All changes are now uploaded at GitHub.

What Next?

In the next Tutorial we will use iCE40HX1K-EVB SRAM memory as video memory to generate video with resolution 640×480 pixels 512 colors.

Then we will teach you how to use the 100Mhz  iCE40-ADC and iCE40-DAC.

Using  iCE40HX1K-EVB as 100Msps Logic Analizer for signals with voltage levels from  1.65V to 5.5V using iCE40-DIO and connected to Sigrok Pulseview and how you can sniff CAN, USB, RFID, I2C, I2S, JTAG, MIDI, MODBUS, SPDIF, SPI, and all other 66 decoding protocols which Sigrok supports.

## All TuxCon 2016 Day 1 talks videos are uploaded on Youtube All TuxCon 2016 talks from Day 1 are now online, some of them are in English, some in Bulgarian language.

## FPGA tutorial – VGA video generation with iCE40HX1K-EVB + iCE40-IO in Verilog iCE40-IO is Open Source Hardware snap-to module for iCE40HX1K-EVB which adds VGA, PS2 and IrDA transciever.

In this tutorial you will learn how to generate VGA video signals, how to capture PS2 keys and how to move object on the video screen.

Here is my setup: I have iCE40HX1K-EVB snap to iCE40-IO with PS2 keboard and VGA connected to it and OLIMEXINO-32U4 as programmer

The tutorial project is on GitHub. Let’s first see example_0.v

Yesterday after sharing my experience with Verilog to silently define signals which you could have type by mistake, there was comment by Andrew Zonenberg, who wrote that you can tell Verilog to consider this error by adding “`default_nettype none” as your first line code. I check and it works fine, so I will use it in all my further sources 🙂 Thanks for the tip Andrew!

The code starts with:

```   `default_nettype none //disable implicit definitions by Verilog

module top( //top module and signals wired to FPGA pins
CLK100MHz,
vga_r,
vga_g,
vga_b,
vga_hs,
vga_vs,
ps2_clk,
ps2_data
);```

here we define top module and what physical signals we will use, these are the CLK100Mhz, VGA R,G,B, H-sync, V-sync, ps2 clock and data

then we must define each of them:

```   input CLK100MHz; // Oscillator input 100Mhz
output [2:0] vga_r; // VGA Red 3 bit
output [2:0] vga_g; // VGA Green 3 bit
output [2:0] vga_b; // VGA Blue 3 bit
output vga_hs; // H-sync pulse
output vga_vs; // V-sync pulse
input ps2_clk; // PS2 clock
input ps2_data; // PS2 data```

as you can see VGA R,G,B signals are 3 bit registers, this way we defini VGA to have 9bit color or 512 different colors

the next part use new keyword parameter, this is how the constants are defined in Verilog:

```  parameter h_pulse = 96; //H-SYNC pulse width 96 * 40 ns (25 Mhz) = 3.84 uS
parameter h_bp = 48; //H-BP back porch pulse width
parameter h_pixels = 640; //H-PIX Number of pixels horisontally
parameter h_fp = 16; //H-FP front porch pulse width
parameter h_pol = 1'b0; //H-SYNC polarity
parameter h_frame = 800; //800 = 96 (H-SYNC) + 48 (H-BP) + 640 (H-PIX) + 16 (H-FP)
parameter v_pulse = 2; //V-SYNC pulse width
parameter v_bp = 33; //V-BP back porch pulse width
parameter v_pixels = 480; //V-PIX Number of pixels vertically
parameter v_fp = 10; //V-FP front porch pulse width
parameter v_pol = 1'b1; //V-SYNC polarity
parameter v_frame = 525; // 525 = 2 (V-SYNC) + 33 (V-BP) + 480 (V-PIX) + 10 (V-FP)

parameter square_size = 10; //size of the square we will move
parameter init_x = 320; //initial square position X
parameter init_y = 240; //initial square position Y```

for VGA timing we will use 25Mhz clock which is made by division by 4 of CLK100Mhz:

```  reg [1:0] clk_div; // 2 bit counter
wire vga_clk;

assign vga_clk = clk_div; // 25Mhz clock = 100Mhz divided by 2-bit counter

always @ (posedge CLK100MHz) begin // 2-bt counter ++ on each positive edge of 100Mhz clock
clk_div <= clk_div + 2'b1;
end```

vga_clk is the bit2 of clk_div which is incrementing on each positive edge of 100Mhz clock

then we define the registers which will hold the VGA signals:

```  reg [2:0] vga_r_r; //VGA color registers R,G,B x 3 bit
reg [2:0] vga_g_r;
reg [2:0] vga_b_r;
reg vga_hs_r; //H-SYNC register
reg vga_vs_r; //V-SYNC register

assign vga_r = vga_r_r; //assign the output signals for VGA to the VGA registers
assign vga_g = vga_g_r;
assign vga_b = vga_b_r;
assign vga_hs = vga_hs_r;
assign vga_vs = vga_vs_r;```

we do want the video generation to start after some time not immediately, and for this we will use two signals:

```  reg [7:0] timer_t = 8'b0; // 8 bit timer with 0 initialization
reg reset = 1;```

8 bit timer will make the necessary delay, reset is internal signal and have nothing in common with the reset button on the board

these registers will hold info where the “video beam” is when the video is generated, we need two of them as one will hold the complete frame even with some of “invisible” video frame, the other just the visible part

```  reg [9:0] c_row; //complete frame register row
reg [9:0] c_col; //complete frame register colum
reg [9:0] c_hor; //visible frame register horisontally
reg [9:0] c_ver; //visible frame register vertically```

this signal flags if the display is enabled or disabled

`  reg disp_en; //display enable flag`

these registers will hold the center coordinates of the visible square we draw on the screen:

```  reg [9:0] sq_pos_x; //position of square center X, Y
reg [9:0] sq_pos_y;```

these registers will hold the upper left and down right coordinates of the square we draw:

```  wire [9:0] l_sq_pos_x; //upper left and down right corners of the square
wire [9:0] r_sq_pos_x;
wire [9:0] u_sq_pos_y;
wire [9:0] d_sq_pos_y;

assign l_sq_pos_x = sq_pos_x - square_size;
assign r_sq_pos_x = sq_pos_x + square_size;
assign u_sq_pos_y = sq_pos_y - square_size;
assign d_sq_pos_y = sq_pos_y + square_size;```

the next registers are for reading the PS2 keyboard:

```  reg [3:0] ps2_cntr; // 4-bit PS2 clock counter
reg [7:0] ps2_data_reg; // 8-bit PS2 data register
reg [7:0] ps2_data_reg_prev; // previous 8-bit PS data register
reg [7:0] ps2_data_reg_prev1; // previous previous 8-bit data register
reg [10:0] ps2_dat_r; // 11-bit complete PS2 frame register

reg [1:0] ps2_clk_buf; // PS2 clock buffer
wire ps2_clk_pos; // PS2 positive edge detected signal

reg u_arr = 0; //PS2 arrow keys detect flags
reg l_arr = 0;
reg d_arr = 0;
reg r_arr = 0;```

the 4-bit counter is for PS2 clock, the three data registers hold three sequential key codes as some keys are transmitted as two bytes when press and three when released
ps2_clk_buf is used to detect rising edge of the PS2 clock:

```  assign ps2_clk_pos = (ps2_clk_buf == 2'b01);
// edge detector positive edge is when the buffer is '10'```

25Mhz clock is used to detect PS2 clock and data:

```  always @ (posedge vga_clk) begin // on each positive edge at 25Mhz clock
ps2_clk_buf[1:0] <= {ps2_clk_buf, ps2_clk};
// shift old value left and get current value of ps2_clk
if(ps2_clk_pos == 1) begin // on positive edge
ps2_cntr <= ps2_cntr + 1;
if(ps2_cntr == 10) begin
// when we got 10 clocks save the PS2 data to ps2_data_reg,
// ps2_data_reg_prev and ps2_data_reg_prev1
ps2_cntr <= 0; // so we have last 3 data values captured from PS2 keyboard
ps2_data_reg <= ps2_dat_r;
ps2_data_reg <= ps2_dat_r;
ps2_data_reg <= ps2_dat_r;
ps2_data_reg <= ps2_dat_r;
ps2_data_reg <= ps2_dat_r;
ps2_data_reg <= ps2_dat_r;
ps2_data_reg <= ps2_dat_r;
ps2_data_reg <= ps2_dat_r;
ps2_data_reg_prev <= ps2_data_reg;
ps2_data_reg_prev1 <= ps2_data_reg_prev;
end
ps2_dat_r <= {ps2_dat_r[9:0], ps2_data}; // data shift left
end```

at this point we have detected when the PS2 keyboard start sending data and captured the transmitted data

here is where we detect is left, right, up and down keys are pressed:

```  if(ps2_data_reg_prev1 == 8'he0 && ps2_data_reg_prev == 8'hf0) begin
// 0xE0 0xF0 sequence means key released
if(ps2_data_reg == 8'h75) begin
u_arr <= 0; //0x75 up key
end
else if(ps2_data_reg == 8'h6b) begin
l_arr <= 0; //0x6B left key
end
else if(ps2_data_reg == 8'h72) begin
d_arr <= 0; //0x72 down key
end
else if(ps2_data_reg == 8'h74) begin
r_arr <= 0; //0x74 right key
end
end
if(ps2_data_reg_prev == 8'he0) begin //0xE0 means key pressed
if(ps2_data_reg == 8'h75) begin
u_arr <= 1; //0x75 up key
end
else if(ps2_data_reg == 8'h6b) begin
l_arr <= 1; //0x6B left key
end
else if(ps2_data_reg == 8'h72) begin
d_arr <= 1; //0x72 down key
end
else if(ps2_data_reg == 8'h74) begin
r_arr <= 1; //0x74 right key
end
end
end```

Now let’s generate the video signal:

```  always @ (posedge vga_clk) begin //25Mhz clock

if(timer_t > 250) begin // generate 10 uS RESET signal
reset <= 0;
end
else begin
reset <= 1; //while in reset display is disabled, suare is set to initial position
timer_t <= timer_t + 1;
disp_en <= 0;
sq_pos_x <= init_x;
sq_pos_y <= init_y;
end```

with timer_t we generate initial 10 uS RESET signal where display is not active and we load initial XY coordinates in the middle of the visible area

this code updates current beam position:

```  if(reset == 1) begin //while RESET is high init counters
c_hor <= 0;
c_ver <= 0;
vga_hs_r <= 1;
vga_vs_r <= 0;
c_row <= 0;
c_col <= 0;
end
else begin // update current beam position
if(c_hor < h_frame - 1) begin
c_hor <= c_hor + 1;
end
else begin
c_hor <= 0;
if(c_ver < v_frame - 1) begin
c_ver <= c_ver + 1;
end
else begin
c_ver <= 0;
end
end
end```

H-sync and V-sync generation:

```   if(c_hor < h_pixels + h_fp + 1 || c_hor > h_pixels + h_fp + h_pulse) begin
// H-SYNC generator
vga_hs_r <= ~h_pol;
end
else begin
vga_hs_r <= h_pol;
end
if(c_ver < v_pixels + v_fp || c_ver > v_pixels + v_fp + v_pulse) begin
//V-SYNC generator
vga_vs_r <= ~v_pol;
end
else begin
vga_vs_r <= v_pol;
end
if(c_hor < h_pixels) begin //c_col and c_row counters are
//updated only in the visible time-frame
c_col <= c_hor;
end
if(c_ver < v_pixels) begin
c_row <= c_ver;
end
if(c_hor < h_pixels && c_ver < v_pixels) begin //VGA color signals are
//enabled only in the visible time frame
disp_en <= 1;
end
else begin
disp_en <= 0;
end```

now to draw the read frame, blue square:

```if(disp_en == 1 && reset == 0) begin
if(c_row == 0 || c_col == 0 || c_row == v_pixels-1 || c_col == h_pixels-1) begin //generate red frame with size 640x480
vga_r_r <= 7;
vga_g_r <= 0;
vga_b_r <= 0;
end
else if(c_col > l_sq_pos_x && c_col < r_sq_pos_x && c_row > u_sq_pos_y && c_row < d_sq_pos_y) begin //generate blue square
vga_r_r <= 0;
vga_g_r <= 0;
vga_b_r <= 7;
end
else begin //everything else is black
vga_r_r <= 0;
vga_g_r <= 0;
vga_b_r <= 0;
end
end
else begin //when display is not enabled everything is black
vga_r_r <= 0;
vga_g_r <= 0;
vga_b_r <= 0;
end```

you can change the colors by editing the RGB values above

once per frame update the square position depend on key pressed:

```  if(c_row == 1 && c_col == 1) begin //once per video frame
if(u_arr) begin
sq_pos_y <= sq_pos_y - 1;
end;

if(d_arr) begin
sq_pos_y <= sq_pos_y + 1;
end;

if(l_arr) begin
sq_pos_x <= sq_pos_x - 1;
end;

if(r_arr) begin
sq_pos_x <= sq_pos_x + 1;
end;
end```

now let’s save the code as example.v, synthesize and program.
Here is what we see: when we press and hold arrow keys the square is moving across the screen yey! but there is problem if we reach the end of frame the square go outside it 🙂 How we can fix this?

Let’s go again to the code which describe the position update, obviously we have to add another if with checking if the square is at the frame ends:

```  if(c_row == 1 && c_col == 1) begin //once per video frame
if(u_arr) begin
if (sq_pos_y > square_size) begin
sq_pos_y <= sq_pos_y - 1;
end
end;

if(d_arr) begin
if (sq_pos_y < (v_pixels - 1 - square_size)) begin
sq_pos_y <= sq_pos_y + 1;
end
end;

if(l_arr) begin
if (sq_pos_x > square_size) begin
sq_pos_x <= sq_pos_x - 1;
end
end;

if(r_arr) begin
if (sq_pos_x < (h_pixels - 1 - square_size)) begin
sq_pos_x <= sq_pos_x + 1;
end
end;
end```

now the square will never go outside! let’s save the code  (it’s also saved on GitHub as example_1.v) and synthesize and program: OK, what else we can change? To keep the button pressed all the time to move the square is boring, let’s make it to move once we just press and release the key without need to keep it all the time pressed.
we can do this by commenting this code which clears the key flags:

```/* if(ps2_data_reg_prev1 == 8'he0 && ps2_data_reg_prev == 8'hf0) begin // 0xE0 0xF0 sequaence means key released
if(ps2_data_reg == 8'h75) begin
u_arr <= 0; //0x75 up key
end
else if(ps2_data_reg == 8'h6b) begin
l_arr <= 0; //0x6B left key
end
else if(ps2_data_reg == 8'h72) begin
d_arr <= 0; //0x72 down key
end
else if(ps2_data_reg == 8'h74) begin
r_arr <= 0; //0x74 right key
end
end
*/```

Now even when you press the key once the square keep moving in this direction until hit the ‘wall’ then stops! This code is saved on GitHub as example_2.v.

Can we make it bounce? Sure we can, we just have to update key status with reverse key when the square hit the wall:

```  if(c_row == 1 && c_col == 1) begin //once per video frame
if(u_arr) begin
if (sq_pos_y > square_size) begin
sq_pos_y <= sq_pos_y - 1;
end
else begin  // change direction when hit wall
u_arr <= 0;
d_arr <= 1;
end
end;

if(d_arr) begin
if (sq_pos_y < (v_pixels - 1 - square_size)) begin
sq_pos_y <= sq_pos_y + 1;
end
else begin
d_arr <= 0;
u_arr <= 1;
end
end;

if(l_arr) begin
if (sq_pos_x > square_size) begin
sq_pos_x <= sq_pos_x - 1;
end
else begin
l_arr <= 0;
r_arr <= 1;
end
end;

if(r_arr) begin
if (sq_pos_x < (h_pixels - 1 - square_size)) begin
sq_pos_x <= sq_pos_x + 1;
end
else begin
r_arr <= 0;
l_arr <= 1;
end
end;

end```

Let’s save and compile! What? We got error!

``` example.blif:1750: fatal error: net `d_arr' has multiple drivers
Makefile:11: recipe for target 'example.asc' failed
make: *** [example.asc] Error 1```

What does this means? d_arr register where we store the key direction has multiply drivers! Looking in the code we see that we assign d_arr in two different always blocks.
In FPGA all processes are performed in parallel, so if we assign one signal in two different blocks we will never know which assignment when is performed and this is considered error in the behavior description.
What we see is that both always blocks are executed on positive edge of vga_clk, so we can just merge them by copy:

``` ps2_clk_buf[1:0] <= {ps2_clk_buf, ps2_clk}; // shift old value left and get current value of ps2_clk
if(ps2_clk_pos == 1) begin // on positive edge
ps2_cntr <= ps2_cntr + 1;
if(ps2_cntr == 10) begin // when we got 10 clocks save the PS2 data to ps2_data_reg, ps2_data_reg_prev and ps2_data_reg_prev1
ps2_cntr <= 0; // so we have last 3 data values captured from PS2 keyboard
ps2_data_reg <= ps2_dat_r;
ps2_data_reg <= ps2_dat_r;
ps2_data_reg <= ps2_dat_r;
ps2_data_reg <= ps2_dat_r;
ps2_data_reg <= ps2_dat_r;
ps2_data_reg <= ps2_dat_r;
ps2_data_reg <= ps2_dat_r;
ps2_data_reg <= ps2_dat_r;
ps2_data_reg_prev <= ps2_data_reg;
ps2_data_reg_prev1 <= ps2_data_reg_prev;
end
ps2_dat_r <= {ps2_dat_r[9:0], ps2_data}; // data shift left
end

if(ps2_data_reg_prev == 8'he0) begin //0xE0 means key pressed
if(ps2_data_reg == 8'h75) begin
u_arr <= 1; //0x75 up key
end
else if(ps2_data_reg == 8'h6b) begin
l_arr <= 1; //0x6B left key
end
else if(ps2_data_reg == 8'h72) begin
d_arr <= 1; //0x72 down key
end
else if(ps2_data_reg == 8'h74) begin
r_arr <= 1; //0x74 right key
end
end```

after the video generation and delete of first always block. In GitHub this code is saved as example_3.v

Now code is synthesized and we can program the FPGA. The square is bouncing to the frame every time it hit it!

We will leave up to you to hack further like to change square move speed etc!

## New Project: Using A20-OLinuXino-MICRO as framegrabber with easyCap Armando Basile submitted interesting project with A20-OLinuXino-MICRO to our Project section. He is using A20-OLinuXino-MICRO and easyCap framegrabber together to capture pictures.

You can see his project in action on the video below:

## Building A20-OLinuXino-MICRO Debian image with hardware accelerated video We made new image for A20-OLiniuXino which uses the hardware accelerated video. The process how to build the image is described here.

All you have to change is to use new Debian rootfs for point.8 from here.

and new script.bin for point.7 from here.

The complete image ready to write on SD-card is here.

## Building Debian Linux bootable SD card with hardware accelerated video decoding and Kernel 3.4 for A10-OLinuXino-LIME ## 1. Setup of the toolchain

You should make sure you have the tools for building the Linux Kernel and install them if you don’t have them. To install new software you should be with super user rights on your Linux machine, so do this type in a terminal.

`\$ sudo su`

you will be asked for your password and then your prompt will change to # which means you are now the super user, all future commands should be run in this mode.

First update apt-get links by typing

`# apt-get update`

Install the toolchain by typing the following.

`# apt-get install gcc-4.7-arm-linux-gnueabihf ncurses-dev uboot-mkimage build-essential git`

This will install: GCC compiler used to compile the kernal, The kernel config menu
uboot make image which is required to allow the SD card to book into the linux image, Git which allows you to download from the github which holds source code for some of the system, Some other tools for building the kernel

Note that if you use debian may be you will need to add

`deb http://www.emdebian.org/debian squeeze main`

in the file below:

`/etc/apt/sources.list`

after the installation you now have all tools to make your very own A10 kernel image!

## 2. Building Uboot

For problems around u-boot use Linux-Sunxi mailing list at Google Groups: https://groups.google.com/forum/#!forum/linux-sunxi

First let’s make the directory where we will build the A10-OLinuXino-Micro linux:

```# mkdir A10_kernel_3.4/
# cd A10_kernel_3.4/```

Then let’s download the uboot sources from GitHub repository, note there are lot of branches but you have to use sunxi branch.

Note that the A10-OLinuXino-Lime board u-boot is tested with the next branch:

```# git rev-parse --verify HEAD
4e491b03b53bd89af3065fc325a99106d0161998```

`# git clone -b sunxi https://github.com/linux-sunxi/u-boot-sunxi.git`

`# cd u-boot-sunxi/`

With the following command you can start the uboot build:

`# make A10-OLinuXino-Lime CROSS_COMPILE=arm-linux-gnueabihf-`

At the end of the process you can check if everything is OK by

```# ls u-boot.bin u-boot-sunxi-with-spl.bin spl/sunxi-spl.bin
spl/sunxi-spl.bin u-boot.bin u-boot-sunxi-with-spl.bin```

If you got these files everything is complete, well done so far

`# cd ..`

You should be in the following directory

`/home/user/A10_kernel_3.4/#`

## 3. Building kernel sources for A10-OLinuXino-Lime

The Allwinner Linux-Sunxi community Kernel is maintained by Alejandro Mery aka mnemoc on Freenode irc. You can find him in #linux-sunxi or #olimex channel, if something is broken with the Linux Kernel you can contact him or use http://linux-sunxi.org/Mailing_list

Kernel sources for A10 are available on GitHub. Note that the following building is made with the revision below:

```# git rev-parse --verify HEAD
a7350cb6a9ec1aae510e26cdc730f05f12e13f9f```

`# git clone https://github.com/linux-sunxi/linux-sunxi`

`# cd linux-sunxi/`

Here you need from A10 configuration file  a10lime_defconfig. The file contains all kernel module settings.

then copy a10lime_defconfig file to configs directory:

`# cp a10lime_defconfig linux-sunxi/arch/arm/configs/.`

and make:

`# make ARCH=arm a10lime_defconfig`

The result should be:
configuration written to .config

If you wish to make your changes in the kernel configuration do:

`# make ARCH=arm menuconfig`

The menuconfig changes a .config text file, which you can view/edit even with a text editor like vi,nano.
With this command you can add or remove different modules for the different peripherials in the kernel. Be careful when use this as this may cause the kernel to not work properly.

Note that before compiling kernel you have to do a patch related with I2C speed. The patch changes i2c speed from 200kHz to 100kHz.
If you want to use some of olimex’s i2c modules on UEXT then you need from this patch.

and apply the patch:

`# patch -p0 < sunxi-i2c.patch`

The other patch is ralated with A10-OLinuXino-Lime sound.

and apply the patch:

`# patch -p0 < a10_sound.patch`

Note that by default A10-OLinuXino-Lime board there is no audio connectors and if you do not need from audio then you no need from this patch

Now you can continue with kernel image compiling

`# make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4 uImage`

when this finishs you will have uImage ready and the result should be:

```Image Name: Linux-3.4.67+
Created: Mon Sep 16 13:39:04 2013
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 5450904 Bytes = 5323.15 kB = 5.20 MB
Entry Point: 40008000

Now you can build the kernel modules:

```# make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4 INSTALL_MOD_PATH=out modules
# make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4 INSTALL_MOD_PATH=out modules_install```

DONE! At this point you have uboot and kernel modules.

The uImage file is located in linux-sunxi/arch/arm/boot/

The kernel modules are located in

linux-sunxi/out/lib/modules/3.x.xx
where 3.x.xx is kernel version

in our case the directory with modules is:

linux-sunxi/out/lib/modules/3.4.67+

## 4. Format and setup the SD-card

We suggest 4GB class 10 micro sd-card but you can use any card between 2GB and 16GB.

First we have to make the correct card partitions, this is done with fdisk.

Plug SD card into your SD card reader and enter in the terminal

`# ls /dev/sd`

Then press two times <TAB> you will see a list of your sd devices like sda sdb sdc note that some of these devices may be your hard disk so make sure you know which one is your sd card before you proceed as you can damage your HDD if you choose the wrong sd-device. You can do this by unplugging your sd card reader and identify which sd devices remove from the list.

Once you know which device is your sdcard like sda use this text instead of the sdX name in the references below:

`# fdisk /dev/sdX`

then do these steps:

1. p

2. d enter 1
if you have more than one partitition press d while delete them all

3. create the first partition, starting from 2048
n enter p enter 1 enter enter +16M

4. create second partition
n enter p enter 2 enter enter enter

then list the created partitions:
p enter
if you did everything correctly on 4GB card you should see something like:

Disk /dev/sdg: 3980 MB, 3980394496 bytes
123 heads, 62 sectors/track, 1019 cylinders, total 7774208 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Device Boot Start End Blocks Id System
/dev/sdg1 2048 34815 16384 83 Linux
/dev/sdg2 34816 7774207 3869696 83 Linux

7. w

write changes to sd card
now we have to format the file system on the card:

the first partition should be vfat as this is FS which the Allwinner bootloader understands

`# mkfs.vfat /dev/sdX1`

the second should be normal Linux EXT3 FS

`# mkfs.ext3 /dev/sdX2`

## 5. Write the Uboot and sunxi-spl.bin

You should be in /home/user/A10_kernel_3.4/# directory
Note that you have to write u-boot-sunxi-with-spl.bin in /dev/sdX (not sdX1 or sdX2)

`# dd if=u-boot-sunxi/u-boot-sunxi-with-spl.bin of=/dev/sdX bs=1024 seek=8`

## 6. Write kernel uImage you build to the SD-card

You should be in the directory below

/home/user/A10_kernel_3.4/# directory

`# mount /dev/sdX1 /mnt/sd`

copy the Kernel uImage to root directory in partition 1

`# cp linux-sunxi/arch/arm/boot/uImage /mnt/sd`

## 7. Write script.bin file and boot.scr file

script.bin is a file with very important configuration parameters like port GPIO assignments, DDR memory parameters, Video resolution etc,

`# cp script.bin /mnt/sd`

boot.scr contains your needed uboot commands for loading script.bin, kernel. initrd (optional), setting kernel parameters and booting.
We offer the boot.scr file ready to use but if you whant to change it you can then read https://github.com/linux-sunxi/u-boot-sunxi/wiki

```# cp boot.scr /mnt/sd
# sync
# umount /dev/sdX1```

## 8. Debian rootfs

The Linux Kernel and Uboot are ready, now we have need from Linux distribution rootfs.

Basically the only difference between the different Linux distributions is the rootfs, so if you put Debian rootfs you will have Debian, if you put Ubuntu rootfs it will be Ubuntu etc.

How to build one is a long topic, the good thing is that there are many already pre-built so we can just download one and use.

exit the kernel directory

`# cd ..`

You should be in the directory below

# /home/user/A10_kernel_3.4/

mount your sd card EXT3 FS partition:

```# mkdir /mnt/sd
# mount /dev/sdX2 /mnt/sd```

and unarchive the rootfs

```# tar xzvf a10-olinuxino-lime_2_release.tgz -C /mnt/sd
# ls /mnt/sd```

the right result should be:
bin dev home lost+found mnt proc run selinux sys usr
boot etc lib media opt root sbin srv tmp var

Now you have to replace the new generated kernel modules from /home/user/A10_kernel_3.4/linux-sunxi/out/lib/modules/ to the new debian file system

```# rm -rf /mnt/sd/lib/modules/*
# cp -rfv linux-sunxi/out/lib/modules/3.x.xx+/ /mnt/sd/lib/modules/```

where x.xx is the kernel version
in our case:

`# cp -rfv linux-sunxi/out/lib/modules/3.4.67+/ /mnt/sd/lib/modules/`

replace /lib/firmware folder with the generated /linux-sunxi/out/firmware

```#rm -rf /mnt/sd/lib/firmware/
#cp -rfv linux-sunxi/out/lib/firmware/ /mnt/sd/lib/
# sync
# umount /mnt/sdX2```

at this point you have Debian on your SD card second partition and
you have an SD card ready to boot debian on A10-OLinuXino-Lime

Connect USB-SERIAL-CABLE-F to UEXT Tx.Rx and GND, or connect a HDMI screen. Put the SD-card in A10-OLinuXino-Lime and apply 5V power, you should see Uboot and then Kernel messages on the console