summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames McKenzie <root@ka-ata-killa.panaceas.james.local>2023-05-02 10:57:51 +0100
committerJames McKenzie <root@ka-ata-killa.panaceas.james.local>2023-05-02 10:57:51 +0100
commit429d1ca34aeb0df444f557e86793dbdd1372ccce (patch)
treeb1ff96c966757467d3f9c1f7fcd8073b517c965d
downloadtim_ac3rf_fpga_kit-429d1ca34aeb0df444f557e86793dbdd1372ccce.tar.gz
tim_ac3rf_fpga_kit-429d1ca34aeb0df444f557e86793dbdd1372ccce.tar.bz2
tim_ac3rf_fpga_kit-429d1ca34aeb0df444f557e86793dbdd1372ccce.zip
working demo code for fpga board
-rw-r--r--.gitignore4
-rw-r--r--.gitmodules15
-rw-r--r--Makefile64
-rw-r--r--src/.gitignore1
m---------src/abc0
-rw-r--r--src/evb-yosys-demo/.gitignore7
-rw-r--r--src/evb-yosys-demo/ice40-io-video/Makefile52
-rw-r--r--src/evb-yosys-demo/ice40-io-video/example.v372
-rw-r--r--src/evb-yosys-demo/ice40-io-video/example_0.v255
-rw-r--r--src/evb-yosys-demo/ice40-io-video/example_1.v263
-rw-r--r--src/evb-yosys-demo/ice40-io-video/example_2.v263
-rw-r--r--src/evb-yosys-demo/ice40-io-video/example_3.v277
-rw-r--r--src/evb-yosys-demo/ice40-io-video/example_4.v313
-rw-r--r--src/evb-yosys-demo/ice40-io-video/example_5.v317
-rw-r--r--src/evb-yosys-demo/ice40-io-video/example_6.v364
-rw-r--r--src/evb-yosys-demo/ice40-io-video/example_7.v371
-rw-r--r--src/evb-yosys-demo/ice40-io-video/ice40-io-video.pcf14
-rw-r--r--src/evb-yosys-demo/ice40hx8k-evb/.gitignore4
-rw-r--r--src/evb-yosys-demo/ice40hx8k-evb/Makefile49
-rw-r--r--src/evb-yosys-demo/ice40hx8k-evb/README6
-rw-r--r--src/evb-yosys-demo/ice40hx8k-evb/example.v66
-rw-r--r--src/evb-yosys-demo/ice40hx8k-evb/ice40hx8k-evb.pcf5
m---------src/flashrom0
m---------src/icestorm0
m---------src/nextpnr0
m---------src/yosys0
26 files changed, 3082 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9f9860a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+bin/
+sbin/
+share/
+
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..c86d273
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,15 @@
+[submodule "src/yosys"]
+ path = src/yosys
+ url = https://github.com/YosysHQ/yosys
+[submodule "src/nextpnr"]
+ path = src/nextpnr
+ url = https://github.com/YosysHQ/nextpnr
+[submodule "src/icestorm"]
+ path = src/icestorm
+ url = https://github.com/YosysHQ/icestorm
+[submodule "src/abc"]
+ path = src/abc
+ url = https://github.com/YosysHQ/abc
+[submodule "src/flashrom"]
+ path = src/flashrom
+ url = https://github.com/flashrom/flashrom
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..6104516
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,64 @@
+PREFIX=${PWD}
+
+
+default:src/tools.stamp src/evb-yosys-demo.stamp
+
+src/evb-yosys-demo.stamp: src/tools.stamp
+ ${MAKE} -C src/evb-yosys-demo/ice40hx1k-evb
+ ${MAKE} -C src/evb-yosys-demo/ice40-io-video
+ touch $@
+
+src/tools.stamp: src/nextpnr.stamp src/yosys.stamp src/flashrom.stamp
+ touch $@
+
+src/yosys.stamp:#src/yosys/Makefile
+ # the muppets did not make this easy
+ if [ -d src/yosys/abc]; then ln -s ../abc src/yosys/abc; fi
+ (cd src/abc && rm -f .gitcommit && git checkout .gitcommit && git log -1 --pretty=format:"%h" > .gitcommit )
+ ${MAKE} -C src/yosys PREFIX=${PREFIX} -j 16
+ ${MAKE} -C src/yosys PREFIX=${PREFIX} install
+ (cd src/abc && rm -f .gitcommit && git checkout .gitcommit)
+ /bin/rm -f src/abc/abc-*
+ touch $@
+
+#src/yosys/Makefile:
+# git clone https://github.com/YosysHQ/yosys src/yosys
+
+
+src/nextpnr.stamp: src/nextpnr/build/Makefile
+ ${MAKE} -C src/nextpnr/build
+ ${MAKE} -C src/nextpnr/build install
+ touch $@
+
+src/nextpnr/build/Makefile:src/icestorm.stamp #src/nextpnr/CMakeLists.txt
+ mkdir -p src/nextpnr/build
+ (cd src/nextpnr/build && cmake .. -DARCH=ice40 -DICESTORM_INSTALL_PREFIX=${PREFIX} -DCMAKE_INSTALL_PREFIX=${PREFIX})
+
+
+#src/nextpnr/CMakeLists.tdxt:
+# git clone https://github.com/YosysHQ/nextpnr src/nextpnr
+# (cd src/nextpnr && git submodule init)
+# (cd src/nextpnr && git submodule update)
+
+
+src/icestorm.stamp: #src/icestorm/config.mk
+ ${MAKE} -C src/icestorm PREFIX=${PREFIX}
+ ${MAKE} -C src/icestorm PREFIX=${PREFIX} install
+ touch $@
+
+src/flashrom.stamp: #src/flashrom/Makefile
+ ${MAKE} -C src/flashrom PREFIX=${PREFIX}
+ if [ -d src/flashrom/man8]; then ln -s ../abc src/flashrom/man8; fi
+ ${MAKE} -C src/flashrom PREFIX=${PREFIX} install
+ /bin/rm -f src/flashrom/man8
+ touch $@
+
+
+
+
+
+
+#icestorm/config.mk:
+# git clone https://github.com/YosysHQ/icestorm src/icestorm
+
+
diff --git a/src/.gitignore b/src/.gitignore
new file mode 100644
index 0000000..ac5abaf
--- /dev/null
+++ b/src/.gitignore
@@ -0,0 +1 @@
+*.stamp
diff --git a/src/abc b/src/abc
new file mode 160000
+Subproject 2c1c83f75b8078ced51f92c697da3e712feb3ac
diff --git a/src/evb-yosys-demo/.gitignore b/src/evb-yosys-demo/.gitignore
new file mode 100644
index 0000000..d9ec733
--- /dev/null
+++ b/src/evb-yosys-demo/.gitignore
@@ -0,0 +1,7 @@
+*.json
+*.asc
+*.rpt
+*.log
+ice40-io-video/build/
+ice40hx1k-evb/build/
+
diff --git a/src/evb-yosys-demo/ice40-io-video/Makefile b/src/evb-yosys-demo/ice40-io-video/Makefile
new file mode 100644
index 0000000..8b5a9b1
--- /dev/null
+++ b/src/evb-yosys-demo/ice40-io-video/Makefile
@@ -0,0 +1,52 @@
+PREFIX=../../..
+
+YOSYS=${PREFIX}/bin/yosys
+NEXTPNR=${PREFIX}/bin/nextpnr-ice40
+ICEPACK=${PREFIX}/bin/icepack
+ICETIME=${PREFIX}/bin/icetime
+FLASH=${PREFIX}/bin/flash
+
+BUILDDIR = ./build
+FPGA_TYPE = hx8k
+FPGA_PKG = ct256
+PCF = ice40-io-video.pcf
+RMDIR = rmdir
+
+# Targets
+example: $(BUILDDIR)/example.rpt $(BUILDDIR)/example.bin
+example_0: $(BUILDDIR)/example_0.rpt $(BUILDDIR)/example_0.bin
+example_1: $(BUILDDIR)/example_1.rpt $(BUILDDIR)/example_1.bin
+example_2: $(BUILDDIR)/example_2.rpt $(BUILDDIR)/example_2.bin
+example_3: $(BUILDDIR)/example_3.rpt $(BUILDDIR)/example_3.bin
+example_4: $(BUILDDIR)/example_4.rpt $(BUILDDIR)/example_4.bin
+example_5: $(BUILDDIR)/example_5.rpt $(BUILDDIR)/example_5.bin
+example_6: $(BUILDDIR)/example_6.rpt $(BUILDDIR)/example_6.bin
+example_7: $(BUILDDIR)/example_7.rpt $(BUILDDIR)/example_7.bin
+
+flash: $(BUILDDIR)/example.bin
+ ${FLASH} ${BUILDDIR}/example.bin
+
+
+$(BUILDDIR)/%.json: %.v
+ @mkdir -p $(@D)
+ ${YOSYS} -ql $(subst .json,,$@).log -p 'synth_ice40 -abc9 -device u -top top -json $@' $<
+
+%.asc: %.json
+ ${NEXTPNR} --${FPGA_TYPE} --package ${FPGA_PKG} --json $< --pcf ${PCF} --asc $@
+
+%.bin: %.asc
+ ${ICEPACK} $< $@
+
+%.rpt: %.asc
+ ${ICETIME} -d $(FPGA_TYPE) -mtr $@ $<
+
+all: example example_0 example_1 example_2 example_3 example_4 example_5 example_6 example_7
+
+clean:
+ rm -f $(BUILDDIR)/*.asc $(BUILDDIR)/*.bin $(BUILDDIR)/*.rpt $(BUILDDIR)/*.log $(BUILDDIR)/*.json
+ $(RMDIR) $(BUILDDIR)
+
+# Uncomment this line if you want to keep the intermediate .json and .asc files
+# .PRECIOUS: $(BUILDDIR)/%.json %.asc
+
+.PHONY: all prog clean example example_0 example_1 example_2 example_3 example_4 example_5 example_6 example_7
diff --git a/src/evb-yosys-demo/ice40-io-video/example.v b/src/evb-yosys-demo/ice40-io-video/example.v
new file mode 100644
index 0000000..500aca6
--- /dev/null
+++ b/src/evb-yosys-demo/ice40-io-video/example.v
@@ -0,0 +1,372 @@
+`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
+);
+
+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
+
+
+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
+
+reg [1:0] clk_div; // 2 bit counter
+wire vga_clk;
+
+assign vga_clk = clk_div[1]; // 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
+
+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;
+
+reg [7:0] timer_t = 8'b0; // 8 bit timer with 0 initialization
+reg reset = 1;
+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
+
+reg disp_en; //display enable flag
+
+reg [9:0] sq_pos_x; //position of square center X, Y
+reg [9:0] sq_pos_y;
+
+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;
+
+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;
+
+reg [20:0] arr_timer; // delay between key service
+
+reg [19:0] sq_figure [0:19];
+
+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
+
+assign ps2_clk_pos = (ps2_clk_buf == 2'b01); // edge detector positive edge is when the buffer is '10'
+
+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
+
+ if(reset == 1) begin //while RESET is high init counters
+
+
+ sq_figure[0][19:0] <= 20'b00000000000000000000;
+ sq_figure[1][19:0] <= 20'b00000001111100000000;
+ sq_figure[2][19:0] <= 20'b00000111111111000000;
+ sq_figure[3][19:0] <= 20'b00011111111111110000;
+ sq_figure[4][19:0] <= 20'b00111111111111111000;
+ sq_figure[5][19:0] <= 20'b00111111111111111000;
+ sq_figure[6][19:0] <= 20'b01111111111111111100;
+ sq_figure[7][19:0] <= 20'b01111111111111111100;
+ sq_figure[8][19:0] <= 20'b11111111111111111110;
+ sq_figure[9][19:0] <= 20'b11111111111111111110;
+ sq_figure[10][19:0] <= 20'b11111111111111111110;
+ sq_figure[11][19:0] <= 20'b11111111111111111110;
+ sq_figure[12][19:0] <= 20'b11111111111111111110;
+ sq_figure[13][19:0] <= 20'b01111111111111111100;
+ sq_figure[14][19:0] <= 20'b01111111111111111100;
+ sq_figure[15][19:0] <= 20'b00111111111111111000;
+ sq_figure[16][19:0] <= 20'b00111111111111111000;
+ sq_figure[17][19:0] <= 20'b00011111111111110000;
+ sq_figure[18][19:0] <= 20'b00000111111111000000;
+ sq_figure[19][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
+ 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
+ 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
+ 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 <= 7;
+ //vga_g_r <= 0;
+ //vga_b_r <= 7;
+ if(sq_figure[sq_fig_y][sq_fig_x] == 1) begin
+ vga_r_r <= 0;
+ vga_g_r <= 7;
+ vga_b_r <= 0;
+ end
+ else begin
+ vga_r_r <= 0;
+ vga_g_r <= 0;
+ vga_b_r <= 7;
+ end
+ 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
+
+ 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
+
+ ps2_clk_buf[1:0] <= {ps2_clk_buf[0], 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[7] <= ps2_dat_r[0];
+ ps2_data_reg[6] <= ps2_dat_r[1];
+ ps2_data_reg[5] <= ps2_dat_r[2];
+ ps2_data_reg[4] <= ps2_dat_r[3];
+ ps2_data_reg[3] <= ps2_dat_r[4];
+ ps2_data_reg[2] <= ps2_dat_r[5];
+ ps2_data_reg[1] <= ps2_dat_r[6];
+ ps2_data_reg[0] <= ps2_dat_r[7];
+ 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_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
+*/
+ arr_timer <= arr_timer + 1;
+
+ if(arr_timer == 0) begin
+
+ sq_figure[8][19:0] <= sq_figure[8][19:0] ^ 20'b00000001111000000000;
+ sq_figure[9][19:0] <= sq_figure[9][19:0] ^ 20'b00000001111000000000;
+ sq_figure[10][19:0] <= sq_figure[10][19:0] ^ 20'b00000001111000000000;
+ sq_figure[11][19:0] <= sq_figure[11][19:0] ^ 20'b00000001111000000000;
+
+
+ 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
+
+
+end
+
+endmodule
diff --git a/src/evb-yosys-demo/ice40-io-video/example_0.v b/src/evb-yosys-demo/ice40-io-video/example_0.v
new file mode 100644
index 0000000..23025e6
--- /dev/null
+++ b/src/evb-yosys-demo/ice40-io-video/example_0.v
@@ -0,0 +1,255 @@
+`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
+);
+
+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
+
+
+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
+
+reg [1:0] clk_div; // 2 bit counter
+wire vga_clk;
+
+assign vga_clk = clk_div[1]; // 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
+
+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;
+
+reg [7:0] timer_t = 8'b0; // 8 bit timer with 0 initialization
+reg reset = 1;
+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
+
+reg disp_en; //display enable flag
+
+reg [9:0] sq_pos_x; //position of square center X, Y
+reg [9:0] sq_pos_y;
+
+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;
+
+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;
+
+assign ps2_clk_pos = (ps2_clk_buf == 2'b01); // edge detector positive edge is when the buffer is '10'
+
+always @ (posedge vga_clk) begin // on each positive edge at 25Mhz clock
+ ps2_clk_buf[1:0] <= {ps2_clk_buf[0], 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[7] <= ps2_dat_r[0];
+ ps2_data_reg[6] <= ps2_dat_r[1];
+ ps2_data_reg[5] <= ps2_dat_r[2];
+ ps2_data_reg[4] <= ps2_dat_r[3];
+ ps2_data_reg[3] <= ps2_dat_r[4];
+ ps2_data_reg[2] <= ps2_dat_r[5];
+ ps2_data_reg[1] <= ps2_dat_r[6];
+ ps2_data_reg[0] <= ps2_dat_r[7];
+ 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_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
+ 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
+
+
+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
+
+ 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
+ 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
+
+ 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
+
+ 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
+
+end
+
+endmodule
diff --git a/src/evb-yosys-demo/ice40-io-video/example_1.v b/src/evb-yosys-demo/ice40-io-video/example_1.v
new file mode 100644
index 0000000..41fab0a
--- /dev/null
+++ b/src/evb-yosys-demo/ice40-io-video/example_1.v
@@ -0,0 +1,263 @@
+`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
+);
+
+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
+
+
+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
+
+reg [1:0] clk_div; // 2 bit counter
+wire vga_clk;
+
+assign vga_clk = clk_div[1]; // 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
+
+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;
+
+reg [7:0] timer_t = 8'b0; // 8 bit timer with 0 initialization
+reg reset = 1;
+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
+
+reg disp_en; //display enable flag
+
+reg [9:0] sq_pos_x; //position of square center X, Y
+reg [9:0] sq_pos_y;
+
+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;
+
+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;
+
+assign ps2_clk_pos = (ps2_clk_buf == 2'b01); // edge detector positive edge is when the buffer is '10'
+
+always @ (posedge vga_clk) begin // on each positive edge at 25Mhz clock
+ ps2_clk_buf[1:0] <= {ps2_clk_buf[0], 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[7] <= ps2_dat_r[0];
+ ps2_data_reg[6] <= ps2_dat_r[1];
+ ps2_data_reg[5] <= ps2_dat_r[2];
+ ps2_data_reg[4] <= ps2_dat_r[3];
+ ps2_data_reg[3] <= ps2_dat_r[4];
+ ps2_data_reg[2] <= ps2_dat_r[5];
+ ps2_data_reg[1] <= ps2_dat_r[6];
+ ps2_data_reg[0] <= ps2_dat_r[7];
+ 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_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
+ 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
+
+
+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
+
+ 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
+ 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
+
+ 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
+
+ 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
+
+end
+
+endmodule
diff --git a/src/evb-yosys-demo/ice40-io-video/example_2.v b/src/evb-yosys-demo/ice40-io-video/example_2.v
new file mode 100644
index 0000000..f9f7f36
--- /dev/null
+++ b/src/evb-yosys-demo/ice40-io-video/example_2.v
@@ -0,0 +1,263 @@
+`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
+);
+
+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
+
+
+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
+
+reg [1:0] clk_div; // 2 bit counter
+wire vga_clk;
+
+assign vga_clk = clk_div[1]; // 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
+
+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;
+
+reg [7:0] timer_t = 8'b0; // 8 bit timer with 0 initialization
+reg reset = 1;
+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
+
+reg disp_en; //display enable flag
+
+reg [9:0] sq_pos_x; //position of square center X, Y
+reg [9:0] sq_pos_y;
+
+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;
+
+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;
+
+assign ps2_clk_pos = (ps2_clk_buf == 2'b01); // edge detector positive edge is when the buffer is '10'
+
+always @ (posedge vga_clk) begin // on each positive edge at 25Mhz clock
+ ps2_clk_buf[1:0] <= {ps2_clk_buf[0], 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[7] <= ps2_dat_r[0];
+ ps2_data_reg[6] <= ps2_dat_r[1];
+ ps2_data_reg[5] <= ps2_dat_r[2];
+ ps2_data_reg[4] <= ps2_dat_r[3];
+ ps2_data_reg[3] <= ps2_dat_r[4];
+ ps2_data_reg[2] <= ps2_dat_r[5];
+ ps2_data_reg[1] <= ps2_dat_r[6];
+ ps2_data_reg[0] <= ps2_dat_r[7];
+ 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_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
+*/ 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
+
+
+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
+
+ 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
+ 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
+
+ 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
+
+ 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
+
+end
+
+endmodule
diff --git a/src/evb-yosys-demo/ice40-io-video/example_3.v b/src/evb-yosys-demo/ice40-io-video/example_3.v
new file mode 100644
index 0000000..2d24702
--- /dev/null
+++ b/src/evb-yosys-demo/ice40-io-video/example_3.v
@@ -0,0 +1,277 @@
+`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
+);
+
+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
+
+
+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
+
+reg [1:0] clk_div; // 2 bit counter
+wire vga_clk;
+
+assign vga_clk = clk_div[1]; // 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
+
+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;
+
+reg [7:0] timer_t = 8'b0; // 8 bit timer with 0 initialization
+reg reset = 1;
+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
+
+reg disp_en; //display enable flag
+
+reg [9:0] sq_pos_x; //position of square center X, Y
+reg [9:0] sq_pos_y;
+
+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;
+
+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;
+
+assign ps2_clk_pos = (ps2_clk_buf == 2'b01); // edge detector positive edge is when the buffer is '10'
+
+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
+
+ 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
+ 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
+
+ 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
+
+ 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
+
+ ps2_clk_buf[1:0] <= {ps2_clk_buf[0], 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[7] <= ps2_dat_r[0];
+ ps2_data_reg[6] <= ps2_dat_r[1];
+ ps2_data_reg[5] <= ps2_dat_r[2];
+ ps2_data_reg[4] <= ps2_dat_r[3];
+ ps2_data_reg[3] <= ps2_dat_r[4];
+ ps2_data_reg[2] <= ps2_dat_r[5];
+ ps2_data_reg[1] <= ps2_dat_r[6];
+ ps2_data_reg[0] <= ps2_dat_r[7];
+ 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_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
+*/ 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
+
+endmodule
diff --git a/src/evb-yosys-demo/ice40-io-video/example_4.v b/src/evb-yosys-demo/ice40-io-video/example_4.v
new file mode 100644
index 0000000..1b38918
--- /dev/null
+++ b/src/evb-yosys-demo/ice40-io-video/example_4.v
@@ -0,0 +1,313 @@
+`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
+);
+
+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
+
+
+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
+
+reg [1:0] clk_div; // 2 bit counter
+wire vga_clk;
+
+assign vga_clk = clk_div[1]; // 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
+
+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;
+
+reg [7:0] timer_t = 8'b0; // 8 bit timer with 0 initialization
+reg reset = 1;
+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
+
+reg disp_en; //display enable flag
+
+reg [9:0] sq_pos_x; //position of square center X, Y
+reg [9:0] sq_pos_y;
+
+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;
+
+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;
+
+reg [19:0] sq_figure [0:19];
+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
+
+
+assign ps2_clk_pos = (ps2_clk_buf == 2'b01); // edge detector positive edge is when the buffer is '10'
+
+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
+
+ if(reset == 1) begin //while RESET is high init counters
+ sq_figure[0][19:0] <= 20'b00000000000000000000;
+ sq_figure[1][19:0] <= 20'b00000001111100000000;
+ sq_figure[2][19:0] <= 20'b00000111111111000000;
+ sq_figure[3][19:0] <= 20'b00011111111111110000;
+ sq_figure[4][19:0] <= 20'b00111111111111111000;
+ sq_figure[5][19:0] <= 20'b00111111111111111000;
+ sq_figure[6][19:0] <= 20'b01111111111111111100;
+ sq_figure[7][19:0] <= 20'b01111111111111111100;
+ sq_figure[8][19:0] <= 20'b11111111111111111110;
+ sq_figure[9][19:0] <= 20'b11111111111111111110;
+ sq_figure[10][19:0] <= 20'b11111111111111111110;
+ sq_figure[11][19:0] <= 20'b11111111111111111110;
+ sq_figure[12][19:0] <= 20'b11111111111111111110;
+ sq_figure[13][19:0] <= 20'b01111111111111111100;
+ sq_figure[14][19:0] <= 20'b01111111111111111100;
+ sq_figure[15][19:0] <= 20'b00111111111111111000;
+ sq_figure[16][19:0] <= 20'b00111111111111111000;
+ sq_figure[17][19:0] <= 20'b00011111111111110000;
+ sq_figure[18][19:0] <= 20'b00000111111111000000;
+ sq_figure[19][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
+ 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
+ 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
+
+ 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 //draw picture from video RAM
+ 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
+ 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
+
+ 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
+
+ ps2_clk_buf[1:0] <= {ps2_clk_buf[0], 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[7] <= ps2_dat_r[0];
+ ps2_data_reg[6] <= ps2_dat_r[1];
+ ps2_data_reg[5] <= ps2_dat_r[2];
+ ps2_data_reg[4] <= ps2_dat_r[3];
+ ps2_data_reg[3] <= ps2_dat_r[4];
+ ps2_data_reg[2] <= ps2_dat_r[5];
+ ps2_data_reg[1] <= ps2_dat_r[6];
+ ps2_data_reg[0] <= ps2_dat_r[7];
+ 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_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
+*/ 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
+
+endmodule
diff --git a/src/evb-yosys-demo/ice40-io-video/example_5.v b/src/evb-yosys-demo/ice40-io-video/example_5.v
new file mode 100644
index 0000000..1cb08fa
--- /dev/null
+++ b/src/evb-yosys-demo/ice40-io-video/example_5.v
@@ -0,0 +1,317 @@
+`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
+);
+
+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
+
+
+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
+
+reg [1:0] clk_div; // 2 bit counter
+wire vga_clk;
+
+assign vga_clk = clk_div[1]; // 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
+
+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;
+
+reg [7:0] timer_t = 8'b0; // 8 bit timer with 0 initialization
+reg reset = 1;
+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
+
+reg disp_en; //display enable flag
+
+reg [9:0] sq_pos_x; //position of square center X, Y
+reg [9:0] sq_pos_y;
+
+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;
+
+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;
+
+reg [19:0] sq_figure [0:19];
+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
+
+
+assign ps2_clk_pos = (ps2_clk_buf == 2'b01); // edge detector positive edge is when the buffer is '10'
+
+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
+
+ if(reset == 1) begin //while RESET is high init counters
+ sq_figure[0][19:0] <= 20'b00000000000000000000;
+ sq_figure[1][19:0] <= 20'b00000001111100000000;
+ sq_figure[2][19:0] <= 20'b00000111111111000000;
+ sq_figure[3][19:0] <= 20'b00011111111111110000;
+ sq_figure[4][19:0] <= 20'b00111111111111111000;
+ sq_figure[5][19:0] <= 20'b00111111111111111000;
+ sq_figure[6][19:0] <= 20'b01111111111111111100;
+ sq_figure[7][19:0] <= 20'b01111111111111111100;
+ sq_figure[8][19:0] <= 20'b11111111111111111110;
+ sq_figure[9][19:0] <= 20'b11111111111111111110;
+ sq_figure[10][19:0] <= 20'b11111111111111111110;
+ sq_figure[11][19:0] <= 20'b11111111111111111110;
+ sq_figure[12][19:0] <= 20'b11111111111111111110;
+ sq_figure[13][19:0] <= 20'b01111111111111111100;
+ sq_figure[14][19:0] <= 20'b01111111111111111100;
+ sq_figure[15][19:0] <= 20'b00111111111111111000;
+ sq_figure[16][19:0] <= 20'b00111111111111111000;
+ sq_figure[17][19:0] <= 20'b00011111111111110000;
+ sq_figure[18][19:0] <= 20'b00000111111111000000;
+ sq_figure[19][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
+ 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
+ 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
+
+ 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 //draw picture from video RAM
+ 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
+ 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
+
+ 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
+
+ ps2_clk_buf[1:0] <= {ps2_clk_buf[0], 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[7] <= ps2_dat_r[0];
+ ps2_data_reg[6] <= ps2_dat_r[1];
+ ps2_data_reg[5] <= ps2_dat_r[2];
+ ps2_data_reg[4] <= ps2_dat_r[3];
+ ps2_data_reg[3] <= ps2_dat_r[4];
+ ps2_data_reg[2] <= ps2_dat_r[5];
+ ps2_data_reg[1] <= ps2_dat_r[6];
+ ps2_data_reg[0] <= ps2_dat_r[7];
+ 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_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
+*/ 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
+ d_arr <= 0;
+ end
+ else if(ps2_data_reg == 8'h6b) begin
+ l_arr <= 1; //0x6B left key
+ r_arr <= 0;
+ end
+ else if(ps2_data_reg == 8'h72) begin
+ d_arr <= 1; //0x72 down key
+ u_arr <= 0;
+ end
+ else if(ps2_data_reg == 8'h74) begin
+ r_arr <= 1; //0x74 right key
+ l_arr <= 0;
+ end
+ end
+
+
+end
+
+endmodule
diff --git a/src/evb-yosys-demo/ice40-io-video/example_6.v b/src/evb-yosys-demo/ice40-io-video/example_6.v
new file mode 100644
index 0000000..5d82994
--- /dev/null
+++ b/src/evb-yosys-demo/ice40-io-video/example_6.v
@@ -0,0 +1,364 @@
+`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
+);
+
+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
+
+
+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
+
+reg [1:0] clk_div; // 2 bit counter
+wire vga_clk;
+
+assign vga_clk = clk_div[1]; // 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
+
+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;
+
+reg [7:0] timer_t = 8'b0; // 8 bit timer with 0 initialization
+reg reset = 1;
+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
+
+reg disp_en; //display enable flag
+
+reg [9:0] sq_pos_x; //position of square center X, Y
+reg [9:0] sq_pos_y;
+
+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;
+
+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;
+
+reg [19:0] arr_timer; // delay between key service
+
+reg [19:0] sq_figure [0:19];
+
+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
+
+assign ps2_clk_pos = (ps2_clk_buf == 2'b01); // edge detector positive edge is when the buffer is '10'
+
+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
+
+ if(reset == 1) begin //while RESET is high init counters
+
+
+ sq_figure[0][19:0] <= 20'b00000000000000000000;
+ sq_figure[1][19:0] <= 20'b00000001111100000000;
+ sq_figure[2][19:0] <= 20'b00000111111111000000;
+ sq_figure[3][19:0] <= 20'b00011111111111110000;
+ sq_figure[4][19:0] <= 20'b00111111111111111000;
+ sq_figure[5][19:0] <= 20'b00111111111111111000;
+ sq_figure[6][19:0] <= 20'b01111111111111111100;
+ sq_figure[7][19:0] <= 20'b01111111111111111100;
+ sq_figure[8][19:0] <= 20'b11111111111111111110;
+ sq_figure[9][19:0] <= 20'b11111111111111111110;
+ sq_figure[10][19:0] <= 20'b11111111111111111110;
+ sq_figure[11][19:0] <= 20'b11111111111111111110;
+ sq_figure[12][19:0] <= 20'b11111111111111111110;
+ sq_figure[13][19:0] <= 20'b01111111111111111100;
+ sq_figure[14][19:0] <= 20'b01111111111111111100;
+ sq_figure[15][19:0] <= 20'b00111111111111111000;
+ sq_figure[16][19:0] <= 20'b00111111111111111000;
+ sq_figure[17][19:0] <= 20'b00011111111111110000;
+ sq_figure[18][19:0] <= 20'b00000111111111000000;
+ sq_figure[19][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
+ 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
+ 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
+ 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 <= 7;
+ //vga_g_r <= 0;
+ //vga_b_r <= 7;
+ 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
+ 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
+
+ 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
+
+ ps2_clk_buf[1:0] <= {ps2_clk_buf[0], 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[7] <= ps2_dat_r[0];
+ ps2_data_reg[6] <= ps2_dat_r[1];
+ ps2_data_reg[5] <= ps2_dat_r[2];
+ ps2_data_reg[4] <= ps2_dat_r[3];
+ ps2_data_reg[3] <= ps2_dat_r[4];
+ ps2_data_reg[2] <= ps2_dat_r[5];
+ ps2_data_reg[1] <= ps2_dat_r[6];
+ ps2_data_reg[0] <= ps2_dat_r[7];
+ 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_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
+*/
+ 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
+
+
+end
+
+endmodule
diff --git a/src/evb-yosys-demo/ice40-io-video/example_7.v b/src/evb-yosys-demo/ice40-io-video/example_7.v
new file mode 100644
index 0000000..dbd0b1c
--- /dev/null
+++ b/src/evb-yosys-demo/ice40-io-video/example_7.v
@@ -0,0 +1,371 @@
+`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
+);
+
+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
+
+
+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
+
+reg [1:0] clk_div; // 2 bit counter
+wire vga_clk;
+
+assign vga_clk = clk_div[1]; // 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
+
+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;
+
+reg [7:0] timer_t = 8'b0; // 8 bit timer with 0 initialization
+reg reset = 1;
+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
+
+reg disp_en; //display enable flag
+
+reg [9:0] sq_pos_x; //position of square center X, Y
+reg [9:0] sq_pos_y;
+
+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;
+
+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;
+
+reg [20:0] arr_timer; // delay between key service
+
+reg [19:0] sq_figure [0:19];
+
+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
+
+assign ps2_clk_pos = (ps2_clk_buf == 2'b01); // edge detector positive edge is when the buffer is '10'
+
+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
+
+ if(reset == 1) begin //while RESET is high init counters
+
+
+ sq_figure[0][19:0] <= 20'b00000000000000000000;
+ sq_figure[1][19:0] <= 20'b00000001111100000000;
+ sq_figure[2][19:0] <= 20'b00000111111111000000;
+ sq_figure[3][19:0] <= 20'b00011111111111110000;
+ sq_figure[4][19:0] <= 20'b00111111111111111000;
+ sq_figure[5][19:0] <= 20'b00111111111111111000;
+ sq_figure[6][19:0] <= 20'b01111111111111111100;
+ sq_figure[7][19:0] <= 20'b01111111111111111100;
+ sq_figure[8][19:0] <= 20'b11111111111111111110;
+ sq_figure[9][19:0] <= 20'b11111111111111111110;
+ sq_figure[10][19:0] <= 20'b11111111111111111110;
+ sq_figure[11][19:0] <= 20'b11111111111111111110;
+ sq_figure[12][19:0] <= 20'b11111111111111111110;
+ sq_figure[13][19:0] <= 20'b01111111111111111100;
+ sq_figure[14][19:0] <= 20'b01111111111111111100;
+ sq_figure[15][19:0] <= 20'b00111111111111111000;
+ sq_figure[16][19:0] <= 20'b00111111111111111000;
+ sq_figure[17][19:0] <= 20'b00011111111111110000;
+ sq_figure[18][19:0] <= 20'b00000111111111000000;
+ sq_figure[19][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
+ 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
+ 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
+ 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 <= 7;
+ //vga_g_r <= 0;
+ //vga_b_r <= 7;
+ 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
+ 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
+
+ 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
+
+ ps2_clk_buf[1:0] <= {ps2_clk_buf[0], 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[7] <= ps2_dat_r[0];
+ ps2_data_reg[6] <= ps2_dat_r[1];
+ ps2_data_reg[5] <= ps2_dat_r[2];
+ ps2_data_reg[4] <= ps2_dat_r[3];
+ ps2_data_reg[3] <= ps2_dat_r[4];
+ ps2_data_reg[2] <= ps2_dat_r[5];
+ ps2_data_reg[1] <= ps2_dat_r[6];
+ ps2_data_reg[0] <= ps2_dat_r[7];
+ 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_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
+*/
+ arr_timer <= arr_timer + 1;
+
+ if(arr_timer == 0) begin
+
+ sq_figure[8][19:0] <= sq_figure[8][19:0] ^ 20'b00000001111000000000;
+ sq_figure[9][19:0] <= sq_figure[9][19:0] ^ 20'b00000001111000000000;
+ sq_figure[10][19:0] <= sq_figure[10][19:0] ^ 20'b00000001111000000000;
+ sq_figure[11][19:0] <= sq_figure[11][19:0] ^ 20'b00000001111000000000;
+
+
+ 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
+
+
+end
+
+endmodule
diff --git a/src/evb-yosys-demo/ice40-io-video/ice40-io-video.pcf b/src/evb-yosys-demo/ice40-io-video/ice40-io-video.pcf
new file mode 100644
index 0000000..1684a64
--- /dev/null
+++ b/src/evb-yosys-demo/ice40-io-video/ice40-io-video.pcf
@@ -0,0 +1,14 @@
+set_io CLK100MHz J3
+set_io vga_r[0] E3
+set_io vga_r[1] H5
+set_io vga_r[2] F3
+set_io vga_g[0] H3
+set_io vga_g[1] F2
+set_io vga_g[2] H6
+set_io vga_b[0] F1
+set_io vga_b[1] H4
+set_io vga_b[2] G2
+set_io vga_hs J4
+set_io vga_vs H2
+set_io ps2_clk G1
+set_io ps2_data J5
diff --git a/src/evb-yosys-demo/ice40hx8k-evb/.gitignore b/src/evb-yosys-demo/ice40hx8k-evb/.gitignore
new file mode 100644
index 0000000..c1fa30b
--- /dev/null
+++ b/src/evb-yosys-demo/ice40hx8k-evb/.gitignore
@@ -0,0 +1,4 @@
+example.bin
+example.blif
+example.asc
+example.rpt
diff --git a/src/evb-yosys-demo/ice40hx8k-evb/Makefile b/src/evb-yosys-demo/ice40hx8k-evb/Makefile
new file mode 100644
index 0000000..1bb5bb0
--- /dev/null
+++ b/src/evb-yosys-demo/ice40hx8k-evb/Makefile
@@ -0,0 +1,49 @@
+PREFIX=../../..
+BINDIR=${PREFIX}/bin
+
+#PREBUILT=/root/projects/tim_ac3rf/prebuild/oss-cad-suite/
+#BINDIR=${PREBUILT}/libexec
+#LD_LIBRARY_PATH:="${PREBUILT}/lib:${LD_LIBRARY_PATH}"
+
+YOSYS=${BINDIR}/yosys
+NEXTPNR=${BINDIR}/nextpnr-ice40
+ICEPACK=${BINDIR}/icepack
+ICETIME=${BINDIR}/icetime
+FLASH=${BINDIR}/flash
+
+BUILDDIR = ./build
+FPGA_TYPE = hx8k
+FPGA_PKG = ct256
+PCF = ice40hx8k-evb.pcf
+RMDIR = rmdir
+
+# Targets
+example: $(BUILDDIR)/example.rpt $(BUILDDIR)/example.bin
+
+flash: $(BUILDDIR)/example.bin
+ ${FLASH} $(BUILDDIR)/example.bin
+
+$(BUILDDIR)/%.json: %.v
+ @mkdir -p $(@D)
+ #LD_LIBRARY_PATH=${LD_LIBRARY_PATH}
+ ${YOSYS} -ql $(subst .json,,$@).log -p 'synth_ice40 -abc9 -device u -top top -json $@' $<
+
+%.asc: %.json
+ ${NEXTPNR} --${FPGA_TYPE} --package ${FPGA_PKG} --json $< --pcf ${PCF} --asc $@
+
+%.bin: %.asc
+ ${ICEPACK} $< $@
+
+%.rpt: %.asc
+ ${ICETIME} -d $(FPGA_TYPE) -mtr $@ $<
+
+all: example
+
+clean:
+ rm -f $(BUILDDIR)/*.asc $(BUILDDIR)/*.bin $(BUILDDIR)/*.rpt $(BUILDDIR)/*.log $(BUILDDIR)/*.json
+ $(RMDIR) $(BUILDDIR)
+
+# Uncomment this line if you want to keep the intermediate .json and .asc files
+# .PRECIOUS: $(BUILDDIR)/%.json %.asc
+
+.PHONY: all prog clean example
diff --git a/src/evb-yosys-demo/ice40hx8k-evb/README b/src/evb-yosys-demo/ice40hx8k-evb/README
new file mode 100644
index 0000000..8e2c1e0
--- /dev/null
+++ b/src/evb-yosys-demo/ice40hx8k-evb/README
@@ -0,0 +1,6 @@
+This example is for iCE40HX1K-EVB board
+
+www.olimex.com/wiki/iCE40HX1K-EVB
+
+you need OLIMEXINO-32U4 set as programmer to program the board
+
diff --git a/src/evb-yosys-demo/ice40hx8k-evb/example.v b/src/evb-yosys-demo/ice40hx8k-evb/example.v
new file mode 100644
index 0000000..0aa36d9
--- /dev/null
+++ b/src/evb-yosys-demo/ice40hx8k-evb/example.v
@@ -0,0 +1,66 @@
+module top( //top module
+ CLK,
+ BUT1,
+ BUT2,
+ LED1,
+ LED2
+);
+
+input CLK; //input 100Mhz clock
+input BUT1; //input signal from button 1
+input BUT2; //input signal from button 2
+output LED1; //output signal to LED1
+output LED2; //output signal to LED2
+
+reg BUT1_r; //register to keep button 1 state
+reg BUT2_r; //register to keep button 2 state
+reg LED1_m0_r; //LED1 value in mode = 0
+reg LED2_m0_r; //LED2 value in mode = 0
+reg LED1_m1_r; //LED1 value in mode = 1
+reg LED2_m1_r; //LED2 value in mode = 1
+reg [14:0] cntr; // 15 bit counter for LED blink timing
+reg [14:0] rst_cnt=0; // 15 bit counter for button debounce
+reg mode=1; //mode set to 1 initially
+reg [11:0] clk_div; // 12 bit counter
+
+wire clk_24KHz; //signal with approx 24KHz clock
+wire reset; //used for button debounce
+
+assign reset = rst_cnt[14]; //reset signal is connected to bit15 of rst_cnt
+assign LED1 = mode ? LED1_m1_r : LED1_m0_r; //multiplexer controlled by mode which connects LED1_m1_r or LED1_m0_r to LED1
+assign LED2 = mode ? LED2_m1_r : LED2_m0_r; //multiplexer controlled by mode which connects LED2_m1_r or LED2_m0_r to LED2
+assign clk_24KHz = clk_div[11]; //100 000 000 Hz / 4096 = 24414 Hz
+
+always @ (posedge CLK) begin //on each positive edge of 100Mhz clock increment clk_div
+ clk_div <= clk_div + 12'b1;
+end
+
+always @ (posedge clk_24KHz) begin //on each positive edge of 24414Hz clock
+ BUT1_r <= BUT1; //capture button 1 state to BUT1_r
+ BUT2_r <= BUT2; //capture button 2 state to BUT2_r
+ cntr <= cntr + 15'd1; //increment cntr LED blink counter
+
+ if(reset == 1'b0) begin //if bit15 of rst_cnt is not set yet
+ rst_cnt <= rst_cnt + 15'd1; //increment the counter rst_cnt
+ end
+
+ if(BUT1_r == 1'b0 && BUT2_r == 1'b0 && reset == 1'b1) begin //if bit15 of rst_cnt is set and both buttons are pressed
+ mode <= mode ^ 1'b1; //toggle the mode
+ rst_cnt <= 15'd0; //clear debounce rst_cnt
+ end
+
+ LED1_m0_r <= ~BUT1_r; //copy inversed state of button 1 to LED1_m0_r
+ LED2_m0_r <= ~BUT2_r; //copy inversed state of button 2 to LED2_m0_r
+
+ if(cntr == 15'd12207) begin //when 0.5s pass
+ LED1_m1_r <= 1'b0; //reset LED1_m1_r
+ LED2_m1_r <= 1'b1; //set LED2_m1_r
+ end
+ if(cntr > 15'd24414) begin //when 1.0s pass
+ cntr <= 15'd0; //clear cntr
+ LED1_m1_r <= 1'b1; //set LED1_m1_r
+ LED2_m1_r <= 1'b0; //reset LED2_m1_r
+ end
+end
+
+endmodule
diff --git a/src/evb-yosys-demo/ice40hx8k-evb/ice40hx8k-evb.pcf b/src/evb-yosys-demo/ice40hx8k-evb/ice40hx8k-evb.pcf
new file mode 100644
index 0000000..3d072ff
--- /dev/null
+++ b/src/evb-yosys-demo/ice40hx8k-evb/ice40hx8k-evb.pcf
@@ -0,0 +1,5 @@
+set_io CLK J3
+set_io BUT1 K11
+set_io BUT2 P13
+set_io LED1 M12
+set_io LED2 R16
diff --git a/src/flashrom b/src/flashrom
new file mode 160000
+Subproject 1776bb46ba6ea3d1ab2ec3f0cd88158aabed740
diff --git a/src/icestorm b/src/icestorm
new file mode 160000
+Subproject d20a5e9001f46262bf0cef220f1a6943946e421
diff --git a/src/nextpnr b/src/nextpnr
new file mode 160000
+Subproject 051bdb12b3b695d74a829a231f3e3bf4d0a2632
diff --git a/src/yosys b/src/yosys
new file mode 160000
+Subproject cee3cb31b98e3b67af3165969c8cfc0616c37e1