diff options
Diffstat (limited to 'src')
23 files changed, 2999 insertions, 0 deletions
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  | 
