Initial commit

Uploading to GitHub
This commit is contained in:
Imants Pulkstenis
2019-07-11 18:01:21 +03:00
commit d18a10f6ea
51 changed files with 85956 additions and 0 deletions
+138
View File
@@ -0,0 +1,138 @@
/*
Module was made using paper:
Coding And Scripting Techniques For FSM Designs With
Synthesis-Optimized, Glitch-Free Outputs
by Clifford E. Cummings Sunburst Design, Inc.
*/
module bin_7segment(
input clk, // clock working with 10kHz
input [15:0] sw, // switches (input)
output [6:0] seg, // individual segments of number
output [3:0] an, // anode to select character
output dp // dot on 7segment display
);
//-------------Internal Constants---------------------------
parameter SIZE = 2;
parameter [SIZE-1:0] ONE = 2'b00,
TWO = 2'b01,
THREE = 2'b10,
FOUR = 2'b11;
reg [SIZE-1:0] state=ONE, next=TWO;
reg [3:0] nibble = 'b0 ;
//---------State register sequential always block-----------
always @(posedge clk ) begin
state <= next;
end
//----Next state & outputs, combinational always block------
always@(state or sw)begin
case(state)
ONE : begin
next <= TWO;
nibble <= sw[3:0];
end
TWO : begin
next <= THREE;
nibble <= sw[7:4];
end
THREE : begin
next <= FOUR;
nibble <= sw[11:8];
end
FOUR : begin
next <= ONE;
nibble <= sw[15:12];
end
endcase
end
assign seg[6] = ( nibble == 4'h2 ||
nibble == 4'h3 ||
nibble == 4'h4 ||
nibble == 4'h5 ||
nibble == 4'h6 ||
nibble == 4'h8 ||
nibble == 4'h9 ||
nibble == 4'hA ||
nibble == 4'hB ||
nibble == 4'hD ||
nibble == 4'hE ||
nibble == 4'hF ) ? 1'b0 : 1'b1;
assign seg[5] = ( nibble == 4'h0 ||
nibble == 4'h4 ||
nibble == 4'h5 ||
nibble == 4'h6 ||
nibble == 4'h8 ||
nibble == 4'h9 ||
nibble == 4'hA ||
nibble == 4'hB ||
nibble == 4'hC ||
nibble == 4'hE ||
nibble == 4'hF ) ? 1'b0 : 1'b1;
assign seg[4] = ( nibble == 4'h0 ||
nibble == 4'h2 ||
nibble == 4'h6 ||
nibble == 4'h8 ||
nibble == 4'hA ||
nibble == 4'hB ||
nibble == 4'hC ||
nibble == 4'hD ||
nibble == 4'hE ||
nibble == 4'hF ) ? 1'b0 : 1'b1;
assign seg[3] = ( nibble == 4'h0 ||
nibble == 4'h2 ||
nibble == 4'h3 ||
nibble == 4'h5 ||
nibble == 4'h6 ||
nibble == 4'h8 ||
nibble == 4'h9 ||
nibble == 4'hB ||
nibble == 4'hC ||
nibble == 4'hD ||
nibble == 4'hE ) ? 1'b0 : 1'b1;
assign seg[2] = ( nibble == 4'h0 ||
nibble == 4'h1 ||
nibble == 4'h3 ||
nibble == 4'h4 ||
nibble == 4'h5 ||
nibble == 4'h6 ||
nibble == 4'h7 ||
nibble == 4'h8 ||
nibble == 4'h9 ||
nibble == 4'hA ||
nibble == 4'hB ||
nibble == 4'hD ) ? 1'b0 : 1'b1;
assign seg[1] = ( nibble == 4'h0 ||
nibble == 4'h1 ||
nibble == 4'h2 ||
nibble == 4'h3 ||
nibble == 4'h4 ||
nibble == 4'h7 ||
nibble == 4'h8 ||
nibble == 4'h9 ||
nibble == 4'hA ||
nibble == 4'hD ) ? 1'b0 : 1'b1;
assign seg[0] = ( nibble == 4'h0 ||
nibble == 4'h2 ||
nibble == 4'h3 ||
nibble == 4'h5 ||
nibble == 4'h6 ||
nibble == 4'h7 ||
nibble == 4'h8 ||
nibble == 4'h9 ||
nibble == 4'hA ||
nibble == 4'hC ||
nibble == 4'hE ||
nibble == 4'hF) ? 1'b0 : 1'b1;
assign dp = 1'b1; //dot
assign an[0] = (state==ONE) ? 1'b0 : 1'b1;
assign an[1] = (state==TWO) ? 1'b0 : 1'b1;
assign an[2] = (state==THREE) ? 1'b0 : 1'b1;
assign an[3] = (state==FOUR) ? 1'b0 : 1'b1;
endmodule
+42
View File
@@ -0,0 +1,42 @@
`include "7segment.v"
module bin_7segment_tb();
reg clk = 1'b0;
reg [15:0] sw = 'b0;
wire [6:0] seg;
wire [3:0] an;
wire dp;
always #1 clk <= ~clk;
always #40 sw <= sw + 1;
initial
begin
#1000;
$finish();
end
initial
begin
$display(" ");
$display("----------------------------------------------");
$display(" Starting Testbench...");
$dumpfile("wave.vcd");
$dumpvars(0);
$display("----------------------------------------------");
$display(" ");
end
bin_7segment test_unit1(
.clk(clk),
.sw(sw),
.seg(seg),
.an(an),
.dp(dp)
);
endmodule
+302
View File
@@ -0,0 +1,302 @@
## This file is a general .xdc for the Basys3 rev B board
## To use it in a project:
## - uncomment the lines corresponding to used pins
## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
## CFGBVS
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
## Clock signal
set_property PACKAGE_PIN W5 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clk]
## Switches
set_property PACKAGE_PIN V17 [get_ports {sw[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {sw[0]}]
set_property PACKAGE_PIN V16 [get_ports {sw[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {sw[1]}]
set_property PACKAGE_PIN W16 [get_ports {sw[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {sw[2]}]
#set_property PACKAGE_PIN W17 [get_ports {sw[3]}]
# set_property IOSTANDARD LVCMOS33 [get_ports {sw[3]}]
#set_property PACKAGE_PIN W15 [get_ports {sw[4]}]
# set_property IOSTANDARD LVCMOS33 [get_ports {sw[4]}]
#set_property PACKAGE_PIN V15 [get_ports {sw[5]}]
# set_property IOSTANDARD LVCMOS33 [get_ports {sw[5]}]
#set_property PACKAGE_PIN W14 [get_ports {sw[6]}]
# set_property IOSTANDARD LVCMOS33 [get_ports {sw[6]}]
set_property PACKAGE_PIN W13 [get_ports {im_p[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {im_p[0]}]
set_property PACKAGE_PIN V2 [get_ports {im_p[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {im_p[1]}]
set_property PACKAGE_PIN T3 [get_ports {im_p[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {im_p[2]}]
set_property PACKAGE_PIN T2 [get_ports {im_p[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {im_p[3]}]
set_property PACKAGE_PIN R3 [get_ports {im_p[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {im_p[4]}]
set_property PACKAGE_PIN W2 [get_ports {im_p[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {im_p[5]}]
set_property PACKAGE_PIN U1 [get_ports {im_p[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {im_p[6]}]
set_property PACKAGE_PIN T1 [get_ports {im_p[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {im_p[7]}]
set_property PACKAGE_PIN R2 [get_ports {im_p[8]}]
set_property IOSTANDARD LVCMOS33 [get_ports {im_p[8]}]
## LEDs
set_property PACKAGE_PIN U16 [get_ports {led[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
set_property PACKAGE_PIN E19 [get_ports {led[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
set_property PACKAGE_PIN U19 [get_ports {led[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
set_property PACKAGE_PIN V19 [get_ports {led[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
set_property PACKAGE_PIN W18 [get_ports {led[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[4]}]
set_property PACKAGE_PIN U15 [get_ports {led[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[5]}]
set_property PACKAGE_PIN U14 [get_ports {led[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[6]}]
set_property PACKAGE_PIN V14 [get_ports {led[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[7]}]
set_property PACKAGE_PIN V13 [get_ports {led[8]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[8]}]
set_property PACKAGE_PIN V3 [get_ports {led[9]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[9]}]
set_property PACKAGE_PIN W3 [get_ports {led[10]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[10]}]
set_property PACKAGE_PIN U3 [get_ports {led[11]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[11]}]
#set_property PACKAGE_PIN P3 [get_ports {led[12]}]
# set_property IOSTANDARD LVCMOS33 [get_ports {led[12]}]
#set_property PACKAGE_PIN N3 [get_ports {led[13]}]
# set_property IOSTANDARD LVCMOS33 [get_ports {led[13]}]
set_property PACKAGE_PIN P1 [get_ports {ledc[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ledc[0]}]
set_property PACKAGE_PIN L1 [get_ports {ledc[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ledc[1]}]
##7 segment display
set_property PACKAGE_PIN W7 [get_ports {seg[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[0]}]
set_property PACKAGE_PIN W6 [get_ports {seg[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[1]}]
set_property PACKAGE_PIN U8 [get_ports {seg[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[2]}]
set_property PACKAGE_PIN V8 [get_ports {seg[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[3]}]
set_property PACKAGE_PIN U5 [get_ports {seg[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[4]}]
set_property PACKAGE_PIN V5 [get_ports {seg[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[5]}]
set_property PACKAGE_PIN U7 [get_ports {seg[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[6]}]
#set_property PACKAGE_PIN V7 [get_ports dp]
# set_property IOSTANDARD LVCMOS33 [get_ports dp]
set_property PACKAGE_PIN U2 [get_ports {an[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[0]}]
set_property PACKAGE_PIN U4 [get_ports {an[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[1]}]
set_property PACKAGE_PIN V4 [get_ports {an[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[2]}]
set_property PACKAGE_PIN W4 [get_ports {an[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[3]}]
##Buttons
set_property PACKAGE_PIN U18 [get_ports btnC]
set_property IOSTANDARD LVCMOS33 [get_ports btnC]
set_property PACKAGE_PIN T18 [get_ports btnU]
set_property IOSTANDARD LVCMOS33 [get_ports btnU]
#set_property PACKAGE_PIN W19 [get_ports btnL]
#set_property IOSTANDARD LVCMOS33 [get_ports btnL]
#set_property PACKAGE_PIN T17 [get_ports btnR]
#set_property IOSTANDARD LVCMOS33 [get_ports btnR]
#set_property PACKAGE_PIN U17 [get_ports btnD]
#set_property IOSTANDARD LVCMOS33 [get_ports btnD]
## FIRST CAMERA
##Pmod Header JXADC
#Sch name = XA1_P
set_property PACKAGE_PIN J3 [get_ports {ov7670_cam2_pwdn}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam2_pwdn}]
#Sch name = XA2_P
set_property PACKAGE_PIN L3 [get_ports {ov7670_cam2_data[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam2_data[0]}]
#Sch name = XA3_P
set_property PACKAGE_PIN M2 [get_ports {ov7670_cam2_data[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam2_data[2]}]
#Sch name = XA4_P
set_property PACKAGE_PIN N2 [get_ports {ov7670_cam2_data[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam2_data[4]}]
#Sch name = XA1_N
set_property PACKAGE_PIN K3 [get_ports {ov7670_cam2_reset}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam2_reset}]
#Sch name = XA2_N
set_property PACKAGE_PIN M3 [get_ports {ov7670_cam2_data[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam2_data[1]}]
#Sch name = XA3_N
set_property PACKAGE_PIN M1 [get_ports {ov7670_cam2_data[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam2_data[3]}]
#Sch name = XA4_N
set_property PACKAGE_PIN N1 [get_ports {ov7670_cam2_data[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam2_data[5]}]
##Pmod Header JA
#Sch name = JA1
set_property PACKAGE_PIN J1 [get_ports {ov7670_cam2_data[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam2_data[6]}]
#Sch name = JA2
set_property PACKAGE_PIN L2 [get_ports {ov7670_cam2_mclk}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam2_mclk}]
#Sch name = JA3
set_property PACKAGE_PIN J2 [get_ports {ov7670_cam2_hs}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam2_hs}]
#Sch name = JA4
set_property PACKAGE_PIN G2 [get_ports {ov7670_cam2_sda}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam2_sda}]
#Sch name = JA7
set_property PACKAGE_PIN H1 [get_ports {ov7670_cam2_data[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam2_data[7]}]
#Sch name = JA8
set_property PACKAGE_PIN K2 [get_ports {ov7670_cam2_pclk}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam2_pclk}]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets ov7670_cam2_pclk]
#Sch name = JA9
set_property PACKAGE_PIN H2 [get_ports {ov7670_cam2_vs}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam2_vs}]
#Sch name = JA10
set_property PACKAGE_PIN G3 [get_ports {ov7670_cam2_scl}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam2_scl}]
## SECOND CAMERA
#Pmod Header JB
#Sch name = JB1
set_property PACKAGE_PIN A14 [get_ports {ov7670_cam1_pwdn}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam1_pwdn}]
#Sch name = JB2
set_property PACKAGE_PIN A16 [get_ports {ov7670_cam1_data[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam1_data[0]}]
#Sch name = JB3
set_property PACKAGE_PIN B15 [get_ports {ov7670_cam1_data[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam1_data[2]}]
#Sch name = JB4
set_property PACKAGE_PIN B16 [get_ports {ov7670_cam1_data[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam1_data[4]}]
#Sch name = JB7
set_property PACKAGE_PIN A15 [get_ports {ov7670_cam1_reset}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam1_reset}]
#Sch name = JB8
set_property PACKAGE_PIN A17 [get_ports {ov7670_cam1_data[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam1_data[1]}]
#Sch name = JB9
set_property PACKAGE_PIN C15 [get_ports {ov7670_cam1_data[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam1_data[3]}]
#Sch name = JB10
set_property PACKAGE_PIN C16 [get_ports {ov7670_cam1_data[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam1_data[5]}]
########################################################
#Pmod Header JC
#Sch name = JC1
set_property PACKAGE_PIN K17 [get_ports {ov7670_cam1_data[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam1_data[6]}]
#Sch name = JC2
set_property PACKAGE_PIN M18 [get_ports {ov7670_cam1_pclk}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam1_pclk}]
create_clock -add -name cam1_pclk -period 40.00 [get_ports {ov7670_cam1_pclk}]
#Sch name = JC3
set_property PACKAGE_PIN N17 [get_ports {ov7670_cam1_hs}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam1_hs}]
#Sch name = JC4
set_property PACKAGE_PIN P18 [get_ports {ov7670_cam1_sda}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam1_sda}]
#Sch name = JC7
set_property PACKAGE_PIN L17 [get_ports {ov7670_cam1_data[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam1_data[7]}]
#Sch name = JC8
set_property PACKAGE_PIN M19 [get_ports {ov7670_cam1_mclk}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam1_mclk}]
#Sch name = JC9
set_property PACKAGE_PIN P17 [get_ports {ov7670_cam1_vs}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam1_vs}]
#Sch name = JC10
set_property PACKAGE_PIN R18 [get_ports {ov7670_cam1_scl}]
set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_cam1_scl}]
########################################################
##VGA Connector
set_property PACKAGE_PIN G19 [get_ports {vgaRed[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vgaRed[0]}]
set_property PACKAGE_PIN H19 [get_ports {vgaRed[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vgaRed[1]}]
set_property PACKAGE_PIN J19 [get_ports {vgaRed[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vgaRed[2]}]
set_property PACKAGE_PIN N19 [get_ports {vgaRed[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vgaRed[3]}]
set_property PACKAGE_PIN N18 [get_ports {vgaBlue[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vgaBlue[0]}]
set_property PACKAGE_PIN L18 [get_ports {vgaBlue[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vgaBlue[1]}]
set_property PACKAGE_PIN K18 [get_ports {vgaBlue[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vgaBlue[2]}]
set_property PACKAGE_PIN J18 [get_ports {vgaBlue[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vgaBlue[3]}]
set_property PACKAGE_PIN J17 [get_ports {vgaGreen[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vgaGreen[0]}]
set_property PACKAGE_PIN H17 [get_ports {vgaGreen[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vgaGreen[1]}]
set_property PACKAGE_PIN G17 [get_ports {vgaGreen[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vgaGreen[2]}]
set_property PACKAGE_PIN D17 [get_ports {vgaGreen[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vgaGreen[3]}]
set_property PACKAGE_PIN P19 [get_ports Hsync]
set_property IOSTANDARD LVCMOS33 [get_ports Hsync]
set_property PACKAGE_PIN R19 [get_ports Vsync]
set_property IOSTANDARD LVCMOS33 [get_ports Vsync]
##USB-RS232 Interface
set_property PACKAGE_PIN B18 [get_ports RsRx]
set_property IOSTANDARD LVCMOS33 [get_ports RsRx]
set_property PACKAGE_PIN A18 [get_ports RsTx]
set_property IOSTANDARD LVCMOS33 [get_ports RsTx]
##USB HID (PS/2)
#set_property PACKAGE_PIN C17 [get_ports PS2Clk]
#set_property IOSTANDARD LVCMOS33 [get_ports PS2Clk]
#set_property PULLUP true [get_ports PS2Clk]
#set_property PACKAGE_PIN B17 [get_ports PS2Data]
#set_property IOSTANDARD LVCMOS33 [get_ports PS2Data]
#set_property PULLUP true [get_ports PS2Data]
##Quad SPI Flash
##Note that CCLK_0 cannot be placed in 7 series devices. You can access it using the
##STARTUPE2 primitive.
#set_property PACKAGE_PIN D18 [get_ports {QspiDB[0]}]
#set_property IOSTANDARD LVCMOS33 [get_ports {QspiDB[0]}]
#set_property PACKAGE_PIN D19 [get_ports {QspiDB[1]}]
#set_property IOSTANDARD LVCMOS33 [get_ports {QspiDB[1]}]
#set_property PACKAGE_PIN G18 [get_ports {QspiDB[2]}]
#set_property IOSTANDARD LVCMOS33 [get_ports {QspiDB[2]}]
#set_property PACKAGE_PIN F18 [get_ports {QspiDB[3]}]
#set_property IOSTANDARD LVCMOS33 [get_ports {QspiDB[3]}]
#set_property PACKAGE_PIN K19 [get_ports QspiCSn]
#set_property IOSTANDARD LVCMOS33 [get_ports QspiCSn]
Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

+275
View File
@@ -0,0 +1,275 @@
%% FPGA image trasform module
% Configuretion script generator
%
% Coordinates for perspective transform matrix
% 640x480
% -------------------------------
% | P2 |
% | P1 |
% | |
% | |
% | |
% | P4 |
% | P3 |
% -------------------------------
% Px = (x , y );
%
% %Pre fefined output image size
% width = 320; % for output image
% higth = 240;
% %Generate settings for:
% camera = 1; % camera 0 or 1
% mode = 0; % from 0 to 3, but 0 is reserved for
%
% P1 = [ 0 , 0 ];
% P2 = [ 639 , 0 ];
% P3 = [ 639 , 479 ];
% P4 = [ 0 , 479 ];
% Or use popup menu
prompt = {'Enter output image width(0-320):','Enter output image higth(0-240):','Enter camera No.(0-1):','Enter mode No.(0-3):'};
dlgtitle = 'Input';
dims = [1 35];
definput = {'320','240','0','1' };
answer = inputdlg(prompt,dlgtitle,dims,definput);
width = str2num(answer{1});
width = min(width, 320);
width = max(width, 1);
higth = str2num(answer{2});
higth = min(higth, 240);
higth = max(higth, 1);
camera = str2num(answer{3});
camera = min(camera, 1);
camera = max(camera, 0);
mode = str2num(answer{4});
mode = min(mode, 3);
mode = max(mode, 0);
%
step = 0.001; % step for lookuptable file generator loop
%
%% reading image
% f = imread('star640x480.jpg');
f = imread('overlay.jpg');
f = im2double(f);
f = mean(f,3);
figure(1);% subplot(2,2,[1,3]);
imshow(f, []);
%% Perspective transform matrix
%
% T = [ 1.4839, 0.23638, 0.0030649; ...
% 0, 1.652, 0; ...
% -4.4516, -207.21, 1];
%
% input corners (using impixel) and compute transform
% use(uncomment):
[c r p] = impixel;
% or use those coordinates(comment if using impixel):
% c = [ P1(1) P2(1) P3(1) P4(1) ]'; % x coordinates
% r = [ P1(2) P2(2) P3(2) P4(2) ]'; % y coordinates
base = [0 0; (width-1) 0; (width-1) (higth-1); 0 (higth-1)]; % output dimentions
tf = fitgeotrans([c r],base,'projective');
% disp('tf = ');
% disp(tf)
T = tf.T;
disp('T =');
format short g
disp(T);
disp('After rounding and converting ');
T = round(T * 2^12) / 2^12 % faster rounding
% T = sfi(T,25,12); % very slow
format
figure(1);%subplot(2,2,[1,3]);
hold on;
% plot red box
plot([c;c(1)],[r;r(1)],'r','Linewidth',2);
text(c(1),r(1)+20,'P1','Color','r');
text(c(2),r(2)+20,'P2','Color','r');
text(c(3),r(3)-20,'P3','Color','r');
text(c(4),r(4)-20,'P4','Color','r');
% % plot lines like in prototype model
% plot([1;1],[0;480],'g','Linewidth',2);
% plot([80;80],[0;480],'g','Linewidth',2);
% plot([160;160],[0;480],'g','Linewidth',2);
% plot([240;240],[0;480],'g','Linewidth',2);
% plot([320;320],[0;480],'g','Linewidth',2);
% plot([400;400],[0;480],'g','Linewidth',2);
% plot([480;480],[0;480],'g','Linewidth',2);
% plot([560;560],[0;480],'g','Linewidth',2);
% plot([639;639],[0;480],'g','Linewidth',2);
%
% plot([0;640],[1;1],'g','Linewidth',2);
% plot([0;640],[80;80],'g','Linewidth',2);
% plot([0;640],[160;160],'g','Linewidth',2);
% plot([0;640],[240;240],'g','Linewidth',2);
% plot([0;640],[320;320],'g','Linewidth',2);
% plot([0;640],[400;400],'g','Linewidth',2);
% plot([0;640],[479;479],'g','Linewidth',2);
%
% F = getframe();
% gg = frame2im(F);
% imwrite(gg,'overlay.jpg'); % save image
hold off;
%% calculating new values
g = zeros(higth, width);
v_tr_all = zeros(numel(f), 3);
n = 0;
for y = 1:size(f, 1),
for x = 1:size(f, 2),
% x and y are from ORIGINAL (untransformed) image from camera
n = n + 1;
v = [x, y, 1];
v_tr = v * T;
v_tr_all(n,:) = v_tr;
w_tr_inv = 1/ v_tr(3);
w_tr_inv = round(w_tr_inv * 2^8) / 2^8;
x_tr = v_tr(1) * w_tr_inv;
y_tr = v_tr(2) * w_tr_inv;
% x_tr = v_tr(1) / v_tr(3);
% y_tr = v_tr(2) / v_tr(3);
%
% x_tr = round(x_tr);
% y_tr = round(y_tr);
x_tr = fix(x_tr); % integer part of real number
y_tr = fix(y_tr);
x_tr = min(x_tr, size(g, 2));
x_tr = max(x_tr, 1);
y_tr = min(y_tr, size(g, 1));
y_tr = max(y_tr, 1);
% x_tr, y_tr are TARGET COORDINATES WHERE TO WRITE DATA
g(y_tr, x_tr) = f(y, x);
end;
end;
figure(2);%subplot(2,1,1);
imshow(g, []);
% plots all calculated x, y and w values
figure(3);%subplot(2,1,2);
plot(v_tr_all);
legend('x', 'y', 'w');
X = ['MAX w = ', num2str(max(v_tr_all(:,3)))];
disp(X),
Y = ['MIN w = ', num2str(min(v_tr_all(:,3)))];
disp(Y),
disp(' ');
% prints w max an min values on plot
text( 0 , 0 , [ X,' ', Y] );
%% Print perspective trasform matrix values in hex
%
% first bit is sign bit, 12bit integer part ans 12bit fraction part
%
Tbin = [];
Thex = [];
for i=1:3
for k=1:3
a = sfi(T(i,k),25,12);
Tbin = [Tbin; a.bin];
Thex = [Thex; a.hex];
end
end
% % Displaying transform matrix in Verilog code style, for easy copying and pasting
% disp('Copy those constants in Verilog code'),
% X = ['TRA_IMG_WIDTH = ''d', num2str(width),','];
% disp(X),
% X = ['TRA_IMG_DEPTH = ''d', num2str(higth),','];
% disp(X),
% a = 0;
% for n=1:3
% for k=1:3
% a = a + 1;
% X = ['T', num2str(n) , num2str(k) ,' = 25''sb', Tbin(a,1), '_' ,Tbin(a,2:13),'_',Tbin(a,14:25),','];
% disp(X),
% end
% end
%
% % Make file for case statement in Verilog
% %
% % This file contains code for loopuptable module
% %
% w_dec = [];
% %w_hex = [];
% w_dec_inv = [];
% temp = ['000000000000']; % just random values
% temp_old = ['000000100000']; % just random values
% for i= -1.5 : step : 4 % min and max w values
% w_dec = [ w_dec; sfi(i,12,8)];
% if (i ~= 0 )
% w_dec_inv = [ w_dec_inv; sfi(1/i,12,8)];
% end
% end
% %w_hex = w_dec.hex;
% w_bin = w_dec.bin;
% w_bin_inv = w_dec_inv.bin;
%
% % lookuptable file generator
% %
% fid = fopen('lookuptable.v', 'wt');
% fprintf(fid, 'module lookuptable();\n');
% fprintf(fid, 'always@(negedge clk) begin\n ');
% fprintf(fid, 'case (w)\n');
%
% for i=1:length(w_bin)
% temp_old = temp;
% temp = w_bin(i,1:12);
% if temp_old == temp
% % if same as previus value, do nothing
% else
% fprintf(fid, '\t12''b%s_%s_%s : r_w_inv <= 12''b%s_%s_%s;\n', w_bin(i,1:1), w_bin(i,2:4), w_bin(i,5:12), w_bin_inv(i,1:1), w_bin_inv(i,2:4), w_bin_inv(i,5:12) );
% end
% end
% fprintf(fid, '\tdefault : r_w_inv <= 12''d1;\n ');% %s_%s_%s;\n ' , w_bin_inv(i,1:12) );
% fprintf(fid, 'endcase;\n');
% fprintf(fid, 'end\n');
% fprintf(fid, 'endmodule');
% disp(' ');
% disp('Text file lookuptable.v write done');disp(' ');
% fclose(fid);
%
%% Making configuretion file for Registers
X = ['Configuration script for CAM',num2str(camera),' and for mode',num2str(mode), ':'];
disp(X),
sw = ufi(mode,2,0);
cam = ufi(camera,1,0);
param = ufi(0,4,0);
value = ufi(width,25,0);
temp = ufi(bin2dec([param.bin , sw.bin , cam.bin]),7,0);
X = ['P', temp.hex];
temp = ufi(bin2dec(value.bin),25,0);
X = [X, temp.hex];
disp(X),
param = ufi(1,4,0);
value = ufi(higth,25,0);
temp = ufi(bin2dec([param.bin , sw.bin , cam.bin]),7,0);
X = ['P', temp.hex];
temp = ufi(bin2dec(value.bin),25,0);
X = [X, temp.hex];
disp(X),
a = 0;
for n=1:3
for k=1:3
a = a + 1;
param = ufi(a+1,4,0);
temp = ufi(bin2dec([param.bin , sw.bin , cam.bin]),7,0);
X = ['P', temp.hex, Thex(a,1:7)];
disp(X),
end
end
+28
View File
@@ -0,0 +1,28 @@
bit=imread('RTU320x240_24bit.bmp'); % 24-bit BMP image RGB888
bit4=bit./17;
bit2=bit./85;
k=1;
fid = fopen('imag_data.csv', 'wt');
for i=240:-1:1 % image is written from the last row to the first row
for j=1:320
r(k)=bit4(i,j,1);
g(k)=bit4(i,j,2);
b(k)=bit4(i,j,3);
mem_place = (i-1)*320+(j-1);
fprintf(fid, 'p\t%d\t%x\t%x\t%x\n', mem_place, r(k), g(k), b(k));
k=k+1;
end
end
disp('Text files write done');disp(' ');
fclose(fid);
%fclose(fid_green);
%fclose(fid_blue);
% fpga4student.com FPGA projects, Verilog projects, VHDL projects
File diff suppressed because it is too large Load Diff
+125
View File
@@ -0,0 +1,125 @@
% Source:
% http://www.johnloomis.org/ece564/notes/tform/planar/html/planar2.html
%
%% Produce orthonormal view from oblique projective image
% read original image
%
clear; close all
filename = 'floor640x480.jpg';
img = im2double(rgb2gray(imread(filename)));
name = 'check2';
msgid = 'Images:initSize:adjustingMag';
warning('off',msgid);
imshow(img);
%
%%
%
% input corners (using impixel) and compute transform
%[c r p] = impixel;
c = [ 320 639 639 320 ]'; % x
r = [ 60 1 479 390 ]'; % y
base = [0 0; 159 0; 159 239; 0 239]; % output dimentions
tf = fitgeotrans([c r],base,'projective');
disp('tf = ');
disp(tf)
%
%%
%
T = tf.T;
disp('T =');
format short g
disp(T);
disp('After rounding and converting ');
T = round(T * 2^12) / 2^12
format
%
%% overlay control points on image
%
imshow(img);
hold on;
plot([c;c(1)],[r;r(1)],'r','Linewidth',2);
%text(c(1),r(1)+20,'0, 11','Color','y');
%text(c(2),r(2)+20,'11, 11','Color','y');
%text(c(3),r(3)-20,'11, 0','Color','y');
%text(c(4),r(4)-20,'0, 0','Color','y');
hold off;
F = getframe();
g = frame2im(F);
imwrite(g,[name '_overlay.jpg']);
%
%% do image transform
%
[xf1, xf1_ref] = imwarp(img,tf);
imshow(xf1)
xf1_ref
imwrite(xf1,[name '_registered.jpg']);
%% Crop image - added not in original code file
%
% xf2 = imcrop(xf1,[476 118 240 240]);
% imshow(xf2)
% imwrite(xf2,[name '_croped.jpg']);
%% Print perspective trasform matrix values in hex
Thex = [];
for i=1:3
for k=1:3
a = sfi(T(i,k),25,12);
Thex = [Thex; a.hex];
end
end
Thex,
%% Calculatin w values
w= [];
w_inv= [];
table = [];
P= [];
Pnew= [];
for x=320:639
for y=0:480
P = [ x , y, 1] * T;
w = [w ; P(3)];
w_inv = [w_inv; 1/P(3) ];
table = [ table; P(3) , 1/P(3) ];
Pnew= [ Pnew ; floor(P(1)/P(3)), floor(P(2)/P(3)) ];
end
end
w = unique(w);
w_inv = unique(w_inv);
min(w),
max(w),
min(w_inv),
max(w_inv),
%% % make fale for case statement in Verilog
w_dec = [];
%w_hex = [];
w_dec_inv = [];
temp = ['0000000000'];
temp_old = ['0000010000'];
for i=1:0.001:2.999
w_dec = [ w_dec; ufi(i,10,8)];
w_dec_inv = [ w_dec_inv; ufi(1/i,10,8)];
end
%w_hex = w_dec.hex;
w_bin = w_dec.bin;
w_bin_inv = w_dec_inv.bin;
fid = fopen('lookuptable.txt', 'wt');
fprintf(fid, 'case (w)\n');
for i=1:length(w_bin)
temp_old = temp;
temp = w_bin(i,1:10);
if temp_old == temp
else
fprintf(fid, '\t10''b%s : r_w_inv <= 10''b%s;\n', w_bin(i,1:10), w_bin_inv(i,1:10) );
end
end
fprintf(fid, '\tdefault : r_w_inv <= 10''b%s;\n ', w_bin(1,1:10) );
fprintf(fid, 'endcase; ');
disp('Text files write done');disp(' ');
fclose(fid);
Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

+76800
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

+2
View File
@@ -0,0 +1,2 @@
# FPGA-camera-inverse-perspective-mapping
Using two OV7670 cameras and Digilent Basys3 board with Xilinx Artix 7 series FPGA performing inverse perspective image mapping and displays result on VGA monitor.
+44
View File
@@ -0,0 +1,44 @@
//
// Original file donwloaded from nandland.com
//
// Outputs byte received from UART
//
//`include "UART_RX.v"
//`include "UART_TX.v"
module UART_Loopback_module #( parameter
DATA_WIDTH = 8
)
( input clk, // Main Clock
input loopback,
input RsRx, // UART RX Data
output RsTx, // UART TX Data
output [DATA_WIDTH-1:0] dout, // data out
output o_TX_Done, // high when transition is done
output o_RX_DV // data valid
);
wire w_TX_Active, w_TX_Serial;
wire [DATA_WIDTH-1:0] w_RX_Byte;
UART_RX #(.CLKS_PER_BIT(868)) UART_RX_Inst
(.clk(clk),
.RsRx(RsRx),
.o_RX_DV(o_RX_DV),
.o_RX_Byte(w_RX_Byte));
UART_TX #(.CLKS_PER_BIT(868)) UART_TX_Inst
(.clk(clk),
.i_TX_DV(o_RX_DV),
.i_TX_Byte(w_RX_Byte),
.o_TX_Active(w_TX_Active),
.o_TX_Serial(w_TX_Serial),
.o_TX_Done(o_TX_Done));
// drive UART line high when transmiter not active
assign RsTx = (w_TX_Active && loopback) ? w_TX_Serial : 1'b1;
assign dout = w_RX_Byte;
endmodule
+54
View File
@@ -0,0 +1,54 @@
`include "UART_Loopback_module.v"
`include "UART_TX.v"
`include "UART_RX.v"
module UART_Loopback_tb();
reg clk = 1'b1;
reg RsRx; // UART RX Data
wire RsTx; // UART TX Data
wire [7:0] dout; // data out
wire o_TX_Done; // high when transition is done
wire o_RX_DV; // data valid
always #1 clk <= ~clk;
initial begin
// starting UART transition
#0 RsRx = 1;
#1736 RsRx = 0;
#1736 RsRx = 1;
#1736 RsRx = 0;
#1736 RsRx = 1;
#1736 RsRx = 0;
#1736 RsRx = 1;
#1736 RsRx = 0;
#1736 RsRx = 1;
#1736 RsRx = 0;
#1736 RsRx = 1;
#100_000;
$finish();
end
initial
begin
$display(" ");
$display("----------------------------------------------");
$display(" Starting Testbench...");
$dumpfile("wave.vcd");
$dumpvars(0);
$display("----------------------------------------------");
$display(" ");
end
UART_Loopback_module Test_Unit(
.clk(clk),
.RsRx(RsRx),
.RsTx(RsTx),
.dout(dout),
.o_TX_Done(o_TX_Done),
.o_RX_DV(o_RX_DV)
);
endmodule
+139
View File
@@ -0,0 +1,139 @@
/////////////////////////////////////////////////////////////////////
// File original code downloaded from http://www.nandland.com
/////////////////////////////////////////////////////////////////////
// This file contains the UART Receiver. This receiver is able to
// receive 8 bits of serial data, one start bit, one stop bit,
// and no parity bit. When receive is complete RsRx will be
// driven high for one clock cycle.
//
// Set Parameter CLKS_PER_BIT as follows:
// CLKS_PER_BIT = (Frequency of i_Clock)/(Frequency of UART)
// Example: 100 MHz Clock, 115200 baud UART
// (100_000_000)/(115200) = 868
//
// File source are form nandland.com
//
module UART_RX
#(parameter CLKS_PER_BIT = 868)
(
input clk,
input RsRx,
output o_RX_DV,
output [7:0] o_RX_Byte
);
localparam IDLE = 3'b000;
localparam RX_START_BIT = 3'b001;
localparam RX_DATA_BITS = 3'b010;
localparam RX_STOP_BIT = 3'b011;
localparam CLEANUP = 3'b100;
reg [9:0] r_Clock_Count = 0;
reg [2:0] r_Bit_Index = 0; //8 bits total
reg [7:0] r_RX_Byte = 0;
reg r_RX_DV = 0;
reg [2:0] r_SM_Main = 0;
// Purpose: Control RX state machine
always @(posedge clk)
begin
case (r_SM_Main)
IDLE :
begin
r_RX_DV <= 1'b0;
r_Clock_Count <= 0;
r_Bit_Index <= 0;
if (RsRx == 1'b0) // Start bit detected
r_SM_Main <= RX_START_BIT;
else
r_SM_Main <= IDLE;
end
// Check middle of start bit to make sure it's still low
RX_START_BIT :
begin
if (r_Clock_Count == (CLKS_PER_BIT)/2)
begin
if (RsRx == 1'b0)
begin
r_Clock_Count <= 0; // reset counter, found the middle
r_SM_Main <= RX_DATA_BITS;
end
else
r_SM_Main <= IDLE;
end
else
begin
r_Clock_Count <= r_Clock_Count + 1;
r_SM_Main <= RX_START_BIT;
end
end // case: RX_START_BIT
// Wait CLKS_PER_BIT-1 clock cycles to sample serial data
RX_DATA_BITS :
begin
if (r_Clock_Count < CLKS_PER_BIT-1)
begin
r_Clock_Count <= r_Clock_Count + 1;
r_SM_Main <= RX_DATA_BITS;
end
else
begin
r_Clock_Count <= 0;
r_RX_Byte[r_Bit_Index] <= RsRx;
// Check if we have received all bits
if (r_Bit_Index < 7)
begin
r_Bit_Index <= r_Bit_Index + 1;
r_SM_Main <= RX_DATA_BITS;
end
else
begin
r_Bit_Index <= 0;
r_SM_Main <= RX_STOP_BIT;
end
end
end // case: RX_DATA_BITS
// Receive Stop bit. Stop bit = 1
RX_STOP_BIT :
begin
// Wait CLKS_PER_BIT-1 clock cycles for Stop bit to finish
if (r_Clock_Count < CLKS_PER_BIT-1)
begin
r_Clock_Count <= r_Clock_Count + 1;
r_SM_Main <= RX_STOP_BIT;
end
else
begin
r_RX_DV <= 1'b1;
r_Clock_Count <= 0;
r_SM_Main <= CLEANUP;
end
end // case: RX_STOP_BIT
// Stay here 1 clock
CLEANUP :
begin
r_SM_Main <= IDLE;
r_RX_DV <= 1'b0;
end
default :
r_SM_Main <= IDLE;
endcase
end
assign o_RX_DV = r_RX_DV;
assign o_RX_Byte = r_RX_Byte;
endmodule // UART_RX
+146
View File
@@ -0,0 +1,146 @@
//////////////////////////////////////////////////////////////////////
// File Downloaded from http://www.nandland.com
//////////////////////////////////////////////////////////////////////
// This file contains the UART Transmitter. This transmitter is able
// to transmit 8 bits of serial data, one start bit, one stop bit,
// and no parity bit. When transmit is complete o_Tx_done will be
// driven high for one clock cycle.
//
// Set Parameter CLKS_PER_BIT as follows:
// CLKS_PER_BIT = (Frequency of clk)/(Frequency of UART)
// Example: 25 MHz Clock, 115200 baud UART
// (25000000)/(115200) = 217
module UART_TX
#(parameter CLKS_PER_BIT = 217)
(
input clk,
input i_TX_DV,
input [7:0] i_TX_Byte,
output o_TX_Active,
output reg o_TX_Serial,
output o_TX_Done
);
localparam IDLE = 3'b000;
localparam TX_START_BIT = 3'b001;
localparam TX_DATA_BITS = 3'b010;
localparam TX_STOP_BIT = 3'b011;
localparam CLEANUP = 3'b100;
reg [2:0] r_SM_Main = 0;
reg [9:0] r_Clock_Count = 0;
reg [2:0] r_Bit_Index = 0;
reg [7:0] r_TX_Data = 0;
reg r_TX_Done = 0;
reg r_TX_Active = 0;
always @(posedge clk)
begin
case (r_SM_Main)
IDLE :
begin
o_TX_Serial <= 1'b1; // Drive Line High for Idle
r_TX_Done <= 1'b0;
r_Clock_Count <= 0;
r_Bit_Index <= 0;
if (i_TX_DV == 1'b1)
begin
r_TX_Active <= 1'b1;
r_TX_Data <= i_TX_Byte;
r_SM_Main <= TX_START_BIT;
end
else
r_SM_Main <= IDLE;
end // case: IDLE
// Send out Start Bit. Start bit = 0
TX_START_BIT :
begin
o_TX_Serial <= 1'b0;
// Wait CLKS_PER_BIT-1 clock cycles for start bit to finish
if (r_Clock_Count < CLKS_PER_BIT)
begin
r_Clock_Count <= r_Clock_Count + 1;
r_SM_Main <= TX_START_BIT;
end
else
begin
r_Clock_Count <= 0;
r_SM_Main <= TX_DATA_BITS;
end
end // case: TX_START_BIT
// Wait CLKS_PER_BIT-1 clock cycles for data bits to finish
TX_DATA_BITS :
begin
o_TX_Serial <= r_TX_Data[r_Bit_Index];
if (r_Clock_Count < CLKS_PER_BIT-1)
begin
r_Clock_Count <= r_Clock_Count + 1;
r_SM_Main <= TX_DATA_BITS;
end
else
begin
r_Clock_Count <= 0;
// Check if we have sent out all bits
if (r_Bit_Index < 7)
begin
r_Bit_Index <= r_Bit_Index + 1;
r_SM_Main <= TX_DATA_BITS;
end
else
begin
r_Bit_Index <= 0;
r_SM_Main <= TX_STOP_BIT;
end
end
end // case: TX_DATA_BITS
// Send out Stop bit. Stop bit = 1
TX_STOP_BIT :
begin
o_TX_Serial <= 1'b1;
// Wait CLKS_PER_BIT-1 clock cycles for Stop bit to finish
if (r_Clock_Count < CLKS_PER_BIT-1)
begin
r_Clock_Count <= r_Clock_Count + 1;
r_SM_Main <= TX_STOP_BIT;
end
else
begin
r_TX_Done <= 1'b1;
r_Clock_Count <= 0;
r_SM_Main <= CLEANUP;
r_TX_Active <= 1'b0;
end
end // case: TX_STOP_BIT
// Stay here 1 clock
CLEANUP :
begin
r_TX_Done <= 1'b1;
r_SM_Main <= IDLE;
end
default :
r_SM_Main <= IDLE;
endcase
end
assign o_TX_Active = r_TX_Active;
assign o_TX_Done = r_TX_Done;
endmodule
+82
View File
@@ -0,0 +1,82 @@
// This module generate address for main memmory, where pixel data will be saved.
//
module address_gen#(
parameter CAM_DATA_WIDTH = 12,
CAM_LINE = 9,
CAM_PIXEL = 10
) (
input clk,
// inputs from camera (or transdormed image)
input i_we,
input [CAM_DATA_WIDTH-1:0] i_data,
input [CAM_LINE-1:0] i_line,
input [CAM_PIXEL-1:0] i_pixel,
// image size and does it need to be resized
input [CAM_LINE-1:0] i_imag_depth,
input [CAM_PIXEL-1:0] i_imag_width,
// input i_imag_resized,
// outputs
output o_we,
output [CAM_DATA_WIDTH-1:0] o_data,
output [16:0] o_addr
);
//------------Internal variables and constants-----------
reg r_we1 = 0;
reg r_we2 = 0;
reg [16:0] r_addr_wr1 = 0;
reg [16:0] r_addr_wr2 = 0;
reg [CAM_DATA_WIDTH-1:0] r_data1 = 0;
reg [CAM_DATA_WIDTH-1:0] r_data2 = 0;
reg [CAM_PIXEL-1:0] r_pixel1 = 0;
// reg [CAM_PIXEL-1:0] r_pixel2 = 0;
reg [CAM_LINE-1:0] r_line1 = 0;
// reg [CAM_LINE-1:0] r_line2 = 0;
//---------------------------------------------------------
always @(posedge clk) begin
// second cycle
if (r_pixel1 < i_imag_width && r_line1 < i_imag_depth ) begin
r_we2 <= r_we1;
// r_line2 <= r_line1;
// r_pixel2 <= r_pixel1;
r_data2 <= r_data1;
r_addr_wr2 <= r_addr_wr1 + r_pixel1[CAM_PIXEL-1:0];
end
else begin
r_we2 <= 'h0;
// r_line2 <= 'h0;
// r_pixel2 <= 'h0;
r_data2 <= 'h0;
r_addr_wr2 <= 'h0;
end
// first cycle
if (i_pixel < i_imag_width && i_line < i_imag_depth ) begin
r_we1 <= i_we;
r_line1 <= i_line;
r_pixel1 <= i_pixel;
r_data1 <= i_data;
r_addr_wr1 <= i_line[CAM_LINE-1:0] * 'd320;
end
else begin
r_we1 <= 'h0;
r_line1 <= 'h0;
r_pixel1 <= 'h0;
r_data1 <= 'h0;
r_addr_wr1 <= 'h0;
end
end
assign o_we = r_we2 ;
assign o_data = r_data2 ;
assign o_addr = r_addr_wr2 ;
endmodule
+41
View File
@@ -0,0 +1,41 @@
// Code from:
// Vivado Design Suite
// User Guide
// Synthesis
// UG901 (v2018.3) December 19, 2018
//
// Dual-Port Block RAM with Two Write Ports
// File: rams_tdp_rf_rf.v
module rams_tdp_rf_rf #( parameter
DEPTH = 307_200,//76_800,
ADDR_WIDTH = 17,
DATA_WIDTH = 8 ) (clka,clkb,ena,enb,wea,web,addra,addrb,dia,dib,doa,dob);
input clka,clkb,ena,enb,wea,web;
input [ADDR_WIDTH-1:0] addra,addrb;
input [DATA_WIDTH-1:0] dia,dib;
output [DATA_WIDTH-1:0] doa,dob;
//reg [ADDR_WIDTH-1:0] ram [ DEPTH - 1 :0];
reg [DATA_WIDTH-1:0] ram [ DEPTH - 1 :0];
reg [DATA_WIDTH-1:0] doa,dob;
always @(posedge clka)
begin
if (ena)
begin
if (wea)
ram[addra] <= dia;
doa <= ram[addra];
end
end
always @(posedge clkb)
begin
if (enb)
begin
if (web)
ram[addrb] <= dib;
dob <= ram[addrb];
end
end
endmodule
+28
View File
@@ -0,0 +1,28 @@
// This module devide FPGA input clock
// by DIVIDER. Result is 50% duty cicle
// pulses.
//
//
module clock_divider #(
parameter DIVIDER =2,
parameter WIDTH =2
) (
input clk,
output clk_out);
reg state=1'b0, next_state=1'b1;
reg [WIDTH-1:0] counter = DIVIDER-1 ;
always@(posedge clk)begin
state <= next_state;
if ( counter == 0) begin
next_state <= ~next_state;
counter <= DIVIDER-1;
end
else if (counter >= 0 )
counter <= counter - 1;
end
assign clk_out = state;
endmodule
+40
View File
@@ -0,0 +1,40 @@
// `timescale [time unit] / [time precision]
`timescale 10 ps / 1 ps
`include "clock_divider_param.v"
module clock_divider_param_tb ();
reg clk = 1'b0;
wire enable;
always #1 clk <= ~clk;
initial
begin
#100;
$finish();
end
initial
begin
$display(" ");
$display("----------------------------------------------");
$display(" Starting Testbench...");
$dumpfile("wave.vcd");
$dumpvars(0);
$display("----------------------------------------------");
$display(" ");
end
clock_divider #(
.DIVIDER(2),
.WIDTH(2)
) test_unit1 (
.clk(clk),
.enable(enable)
);
endmodule
+31
View File
@@ -0,0 +1,31 @@
// This module devide FPGA input clock
// by DIVIDER.
//
//
module clock_enable_param #(
parameter WAIT =1,
parameter WIDTH =1
) (
input clk,
output enable);
reg state=1'b0;
reg [WIDTH-1:0] counter = 1'b0 ;
always@(posedge clk)begin
if(counter == 0)begin
if (state == 1) begin
state <= 0;
counter <= WAIT - 1;
end
else begin
state <= 1;
counter <= 0;
end
end
else counter <= counter -1;
end
assign enable = state;
endmodule
+61
View File
@@ -0,0 +1,61 @@
`include "clock_enable_param.v"
module clock_enable_tb();
reg clk = 1'b0;
wire enable0;
wire enable1;
wire enable2;
wire enable3;
always #1 clk <= ~clk;
initial
begin
#100;
$finish();
end
initial
begin
$display(" ");
$display("----------------------------------------------");
$display(" Starting Testbench...");
$dumpfile("wave.vcd");
$dumpvars(0);
$display("----------------------------------------------");
$display(" ");
end
clock_enable_param test_unit0(
.clk(clk),
.enable(enable0)
);
clock_enable_param #(
.WAIT(2),
.WIDTH(4)
) test_unit1(
.clk(clk),
.enable(enable1)
);
clock_enable_param #(
.WAIT(3),
.WIDTH(8)
)test_unit2(
.clk(clk),
.enable(enable2)
);
clock_enable_param #(
.WAIT(9),
.WIDTH(8)
)test_unit3(
.clk(clk),
.enable(enable3)
);
endmodule
+283
View File
@@ -0,0 +1,283 @@
// Address are in decimal
// value of memory in hex
//
//
module com_to_mem_FSM#( parameter
ADDR_WIDTH = 17,
DATA_WIDTH = 12,
DEPTH = 76_800,
SIZE = 4 // size for for registers FSM
)(
input clk,
input i_enable,
input [7:0] din,
input TX_Done,
input i_RX_DV,
output [3:0] o_state,
output [3:0] o_byte,
output [ADDR_WIDTH-1:0] addr_wr,
output [ADDR_WIDTH-1:0] addr_rd,
output [DATA_WIDTH-1:0] data_wr,
output write,
// output for writing to register memory
output [6:0] o_addr_wr_reg,
output [24:0] o_data_reg,
output o_we_reg
);
//-------------Internal Constants---------------------------
localparam [SIZE-1:0] IDLE = 'h0,
GET_ADDR_W = 'h1,
GET_VALUE_W = 'h2,
WRITE_MEM = 'h3,
GET_ADDR_R = 'h4,
READ_MEM = 'h5,
GET_ADDR_W_REG = 'h6,
GET_VALUE_W_REG = 'h7,
WRITE_MEM_REG = 'h8;
reg [SIZE-1:0] r_state=IDLE,
r_next=IDLE;
reg [2:0] r_addr_byte = 3'h0;
reg [2:0] r_value_byte = 3'h0;
reg r_RX_DV = 1'b0;
reg r_RX_DV_OLD = 1'b0;
reg r_RX_DV_done = 1'b0;
// reg for main memory
reg [ADDR_WIDTH-1:0] r_addr_wr = 'b0;
reg [ADDR_WIDTH-1:0] r_addr_rd = 'b0;
reg [DATA_WIDTH-1:0] r_data_wr = 'b0;
reg r_write = 1'b0;
// reg for register memory
reg [6:0] r_addr_wr_reg = 'b0;
reg [24:0] r_data_reg = 'b0;
reg r_we_reg = 1'b0;
//---------state register sequential always block-----------
always @(posedge clk ) begin
if (i_enable) begin
r_state <= r_next;
end
end
//----next state & outputs, combinational always block------
always@(posedge clk) begin
if ( r_RX_DV == 0 ) begin
r_RX_DV <= i_RX_DV;
end
if (r_RX_DV || r_state == READ_MEM || r_state == WRITE_MEM || r_state == WRITE_MEM_REG ) begin
if (i_enable) begin
case(r_state)
IDLE : begin
if (din==8'h70 && r_RX_DV_OLD == 1'b0 ) // if p
begin
r_next <= GET_ADDR_W;
r_addr_byte <= 'h0;
r_data_wr <= 'h0;
r_addr_wr <= 'h0;
end
else if (din==8'h72 && r_RX_DV_OLD == 1'b0 ) // if r
begin
r_next <= GET_ADDR_R;
r_addr_byte <= 'h0;
r_addr_rd <= 'h0;
end
else if (din==8'h50 && r_RX_DV_OLD == 1'b0 ) // if P
begin
r_next <= GET_ADDR_W_REG;
r_addr_byte <= 'h0;
r_addr_wr_reg <= 'h0;
r_data_reg <= 'h0;
end
end
GET_ADDR_W : begin
if (r_RX_DV_OLD == 1'b0 &&
((din >= 8'h30 && din < 8'h3A) || // if 0-9
(din >= 8'h61 && din <= 8'h66) ) // if a-f
&& r_addr_byte < 'h4 )
begin
if (din >= 8'h30 && din < 8'h3A) begin // if 0-9
r_addr_wr = r_addr_wr * 'd10 + din - 'h30 ;
r_addr_byte <= r_addr_byte + 1;
end
end
else if
(r_RX_DV_OLD == 1'b0 &&
((din >= 8'h30 && din < 8'h3A) || // if 0-9
(din >= 8'h61 && din <= 8'h66) ) // if a-f
&& r_addr_byte == 'h4)
begin
if (din >= 8'h30 && din < 8'h3A) begin // if 0-9
r_addr_wr = r_addr_wr * 'd10 + din - 'h30 ;
r_value_byte <= 'b0;
r_next <= GET_VALUE_W;
end
end
end
GET_VALUE_W : begin
if (r_RX_DV_OLD == 1'b0 &&
((din >= 8'h30 && din < 8'h3A) || // if 0-9
(din >= 8'h61 && din <= 8'h66) ) // if a-f
&& r_value_byte < 'd2 )
begin
if (din >= 8'h30 && din < 8'h3A) begin // if 0-9
r_data_wr = r_data_wr * 'h10 + din - 'h30 ;
r_value_byte <= r_value_byte + 1;
end
else if (din >= 8'h61 && din <= 8'h66) begin // if a-f
r_data_wr = r_data_wr * 'h10 + din - 'h57 ;
r_value_byte <= r_value_byte + 1;
end
end
else if
(r_RX_DV_OLD == 1'b0 &&
((din >= 8'h30 && din < 8'h3A) || // if 0-9
(din >= 8'h61 && din <= 8'h66) ) // if a-f
&& r_value_byte == 'd2)
begin
if (din >= 8'h30 && din < 8'h3A) begin // if 0-9
r_data_wr = r_data_wr * 'h10 + din - 'h30 ;
r_write <= 1'b1;
r_next <= WRITE_MEM;
end
else if (din >= 8'h61 && din <= 8'h66) begin // if a-f
r_data_wr = r_data_wr * 'h10 + din - 'h57 ;
r_write <= 1'b1;
r_next <= WRITE_MEM;
end
end
end
WRITE_MEM : begin
r_write <= 1'b0;
r_addr_byte <= 0;
r_value_byte <= 0;
r_next <= IDLE;
end
GET_ADDR_R : begin
if (r_RX_DV_OLD == 1'b0 &&
((din >= 8'h30 && din < 8'h3A) || // if 0-9
(din >= 8'h61 && din <= 8'h66) ) // if a-f
&& r_addr_byte < 'h4 )
begin
if (din >= 8'h30 && din < 8'h3A) begin // if 0-9
r_addr_rd = r_addr_rd * 'd10 + din - 'h30 ;
r_addr_byte <= r_addr_byte + 1;
end
end
else if
(r_RX_DV_OLD == 1'b0 &&
((din >= 8'h30 && din < 8'h3A) || // if 0-9
(din >= 8'h61 && din <= 8'h66) ) // if a-f
&& r_addr_byte == 'h4)
begin
if (din >= 8'h30 && din < 8'h3A) begin // if 0-9
r_addr_rd = r_addr_rd * 'd10 + din - 'h30 ;
r_next <= READ_MEM;
end
end
end
READ_MEM : begin
r_next <= IDLE;
r_addr_byte <= 0;
end
// wrinting in register memory
GET_ADDR_W_REG : begin
if (r_RX_DV_OLD == 1'b0 &&
((din >= 8'h30 && din < 8'h3A) || // if 0-9
(din >= 8'h61 && din <= 8'h66) ) // if a-f
&& r_addr_byte < 'h1 )
begin
if (din >= 8'h30 && din < 8'h3A) begin // if 0-9
r_addr_wr_reg = r_addr_wr_reg * 'h10 + din - 'h30 ;
r_addr_byte <= r_addr_byte + 1;
end
else if (din >= 8'h61 && din <= 8'h66) begin // if a-f
r_addr_wr_reg = r_addr_wr_reg * 'h10 + din - 'h57 ;
r_value_byte <= r_value_byte + 1;
end
end
else if
(r_RX_DV_OLD == 1'b0 &&
((din >= 8'h30 && din < 8'h3A) || // if 0-9
(din >= 8'h61 && din <= 8'h66) ) // if a-f
&& r_addr_byte == 'h1)
begin
if (din >= 8'h30 && din < 8'h3A) begin // if 0-9
r_addr_wr_reg = r_addr_wr_reg * 'h10 + din - 'h30 ;
r_value_byte <= 'b0;
r_next <= GET_VALUE_W_REG;
end
else if (din >= 8'h61 && din <= 8'h66) begin // if a-f
r_addr_wr_reg = r_addr_wr_reg * 'h10 + din - 'h57 ;
r_value_byte <= 'b0;
r_next <= GET_VALUE_W_REG;
end
end
end
GET_VALUE_W_REG : begin
if (r_RX_DV_OLD == 1'b0 &&
((din >= 8'h30 && din < 8'h3A) || // if 0-9
(din >= 8'h61 && din <= 8'h66) ) // if a-f
&& r_value_byte < 'd6 )
begin
if (din >= 8'h30 && din < 8'h3A) begin // if 0-9
r_data_reg = r_data_reg * 'h10 + din - 'h30 ;
r_value_byte <= r_value_byte + 1;
end
else if (din >= 8'h61 && din <= 8'h66) begin // if a-f
r_data_reg = r_data_reg * 'h10 + din - 'h57 ;
r_value_byte <= r_value_byte + 1;
end
end
else if
(r_RX_DV_OLD == 1'b0 &&
((din >= 8'h30 && din < 8'h3A) || // if 0-9
(din >= 8'h61 && din <= 8'h66) ) // if a-f
&& r_value_byte == 'd6)
begin
if (din >= 8'h30 && din < 8'h3A) begin // if 0-9
r_data_reg = r_data_reg * 'h10 + din - 'h30 ;
r_we_reg <= 1'b1;
r_next <= WRITE_MEM_REG;
end
else if (din >= 8'h61 && din <= 8'h66) begin // if a-f
r_data_reg = r_data_reg * 'h10 + din - 'h57 ;
r_we_reg <= 1'b1;
r_next <= WRITE_MEM_REG;
end
end
end
WRITE_MEM_REG : begin
r_we_reg <= 1'b0;
r_addr_wr_reg <= 1'b0;
r_value_byte <= 1'b0;
r_next <= IDLE;
end
default: r_next <= IDLE; // on error
endcase
r_RX_DV <= 'b0;
end
end
end
//-------------------- assignning combionational logic----------------------------
assign write = r_write;
assign addr_wr = r_addr_wr ;
assign data_wr = r_data_wr ;
assign addr_rd = r_addr_rd ;
assign o_state = r_state;
assign o_byte = (r_state == 'h1 || r_state == 'h4 ) ? r_addr_byte : r_value_byte;
assign o_addr_wr_reg = r_addr_wr_reg;
assign o_data_reg = r_data_reg;
assign o_we_reg = r_we_reg;
endmodule
+95
View File
@@ -0,0 +1,95 @@
// This module is based on Top module: com_to_mem_top.v
// recive comand, addres and data by
// UART and write information in Block RAM
//`include "clock_divider_param.v"
//`include "clock_enable_param.v"
//`include "7segment_v2.v"
//`include "com_to_mem_FSM.v"
//`include "UART_Loopback_module.v"
module com_to_mem #( parameter
WAIT = 1,
WAIT_WIDTH = 2,
ADDR_WIDTH = 17,
DATA_WIDTH = 8,
DEPTH = 76_800
)(
input clk,
input sw,
input i_enable,
// input [DATA_WIDTH-1:0] i_data_rd,
input RsRx, // UART RX Data
output RsTx, // UART TX Data
output [6:0] seg,
output [3:0] an,
// output dp,
output [ADDR_WIDTH-1:0] o_addr_wr,
output [ADDR_WIDTH-1:0] o_addr_rd,
output [DATA_WIDTH-1:0] o_data_wr,
output o_write ,
output [6:0] o_addr_wr_reg,
output [24:0] o_data_reg,
output o_we_reg
);
wire clk10k;
wire [7:0] w_dout;
wire w_RX_DV;
wire w_TX_Done;
wire [3:0] w_state;
wire [3:0] w_byte;
//------ instatiated modules ---------------------------
com_to_mem_FSM #(
.ADDR_WIDTH(ADDR_WIDTH),
.DATA_WIDTH(DATA_WIDTH),
.DEPTH(DEPTH)
) FSM1(
.clk(clk),
.i_enable(i_enable),
.din(w_dout),
.TX_Done(w_TX_Done),
.i_RX_DV(w_RX_DV),
.addr_wr(o_addr_wr),
.addr_rd(o_addr_rd),
.data_wr(o_data_wr),
.write(o_write),
.o_state(w_state),
.o_byte(w_byte),
.o_addr_wr_reg(o_addr_wr_reg),
.o_data_reg(o_data_reg),
.o_we_reg(o_we_reg)
);
bin_7segment bin_7segment1(
.clk(clk10k),
.sw({w_state, w_byte, w_dout}),
.seg(seg),
.an(an),
.dp());
UART_Loopback_module #(
.DATA_WIDTH('d8)
) UART_Loopback_module1
( .clk(clk),
.loopback(sw),
.RsRx(RsRx),
.RsTx(RsTx),
.dout(w_dout),
.o_TX_Done(w_TX_Done),
.o_RX_DV(w_RX_DV));
clock_divider #(
.DIVIDER(1_000),
.WIDTH(24)
) clock_divider7seg (
.clk(clk),
.clk_out(clk10k)
);
endmodule
+487
View File
@@ -0,0 +1,487 @@
// This file is Test Bench for UART to memory module
// its simulates UART comands sent to FPGA to
// write in memmory address value.
// 100MHz clock on Basys3 -> 10ns period
// 50% duty cycle 5ns HIGH and 5ns LOW
//`timescale [time unit] / [time precision]
`timescale 10 ns / 1ns
`include "UART_Loopback_module.v"
`include "UART_TX.v"
`include "UART_RX.v"
`include "clock_divider_param.v"
`include "clock_enable_param.v"
`include "bram.v"
`include "7segment.v"
`include "com_to_mem_FSM_hex.v"
`include "com_to_mem_top.v"
module com_to_mem_tb();
reg clk = 1'b1;
reg RsRx; // UART RX Data
wire RsTx; // UART TX Data
wire [15:0] led;
wire [6:0] seg;
wire [3:0] an;
reg sw=1'b1;
//wire dp;
// 50% duty cycle clock
always #0.5 clk <= ~clk;
initial begin
// starting UART transition
// h70 -> p
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h35 -> 5
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h35 -> 5
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h32 -> 2
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h35 -> 5
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h35 -> 5
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#10_000;
// h72 -> r
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h35 -> 5
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h35 -> 5
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#10_000;
// h70 -> p
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h35 -> 5
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h35 -> 5
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h32 -> 2
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h35 -> 5
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h35 -> 5
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#10_000;
// h72 -> r
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h35 -> 5
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h35 -> 5
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#10_000;
$display(" ");
$display("Use this command to open timing diagram:");
$display("gtkwave -f wave.vcd");
$display("----------------------------------------------");
$finish();
end
initial
begin
$display(" ");
$display("----------------------------------------------");
$display(" Starting Testbench...");
$dumpfile("wave.vcd");
$dumpvars(0);
end
top Test_Unit(
.clk(clk),
.sw(sw),
.RsRx(RsRx),
.RsTx(RsTx),
.led(led),
.seg(seg),
.an(an)//,
// .dp(dp)
);
endmodule
+24
View File
@@ -0,0 +1,24 @@
module debounce_switch(
input clk,
input i_switch,
output o_switch);
parameter c_debounce_limit=250000;// 10ms at 25MHz
reg r_state=1'b0;
reg [17:0] r_count = 0;
always@(posedge clk)begin
if (i_switch != r_state && r_count < c_debounce_limit)
r_count <= r_count +1; //counter
else if (r_count == c_debounce_limit)begin
r_count <=0;
r_state <= i_switch;
end
else
r_count<=0;
end
assign o_switch=r_state;
endmodule
+83
View File
@@ -0,0 +1,83 @@
// Default parameters for image transform module
// Four MSB are actual registers
// next two bits are one of modes selected by swishes. 4 modes are avilable
// LSB are camera bit. avilable two cameras. Camera 0 and camera 1.
//
//
module default_reg_writer #(parameter
CAM_LINE = 9,
CAM_PIXEL = 10,
TRA_IMG_WIDTH = 'd320,
TRA_IMG_DEPTH = 'd240,
T11 = 25'sb0_000000000000_100000000000,
T12 = 25'sb0_000000000000_000000000000,
T13 = 25'sb0_000000000000_000000000000,
T21 = 25'sb0_000000000000_000000000000,
T22 = 25'sb0_000000000000_100000000000,
T23 = 25'sb0_000000000000_000000000000,
T31 = 25'sb0_000000000000_000000000000,
T32 = 25'sb0_000000000000_000000000000,
T33 = 25'sb0_000000000001_000000000000
)(
input clk,
input i_enable,
input i_reset,
output o_configured,
output [6:0] o_addr ,
output [24:0] o_data ,
output o_we
);
// Internal variables and registers
reg r_configured = 0;
reg [6:0] r_divider = 7'b0000001; // this value gives a 127 cycle pause before the initial frame is sent
reg [6:0] r_count = 'b0;
reg [24:0] r_data = 'b0;
reg r_we = 'b0;
//------------------ synchonus logic------------------
always @ (posedge clk) begin
if(i_enable)begin
if (i_reset || r_divider != 0 ) begin
r_count <= 0;
r_divider <= r_divider + 1;
r_configured <= 0;
if (r_divider == 'd127) r_we <= 1;
else r_we <= 0;
end
else if ( r_count < 88 ) begin
r_count <= r_count + 1;
r_we <= 1;
end
end
case (r_count[6:3])
'd0 : r_data[CAM_PIXEL-1:0] <= TRA_IMG_WIDTH;
'd1 : r_data[CAM_LINE-1:0] <= TRA_IMG_DEPTH;
'd2 : r_data <= T11;
'd3 : r_data <= T12;
'd4 : r_data <= T13;
'd5 : r_data <= T21;
'd6 : r_data <= T22;
'd7 : r_data <= T23;
'd8 : r_data <= T31;
'd9 : r_data <= T32;
'd10 : r_data <= T33;
default: begin
r_configured <= 1; // default case just in case do nothing
r_we <= 0;
end
endcase
end
//----------- combinational logic ----------------------
assign o_configured = r_configured;
assign o_addr = r_count;
assign o_data = r_data;
assign o_we = r_we;
endmodule
+67
View File
@@ -0,0 +1,67 @@
// This file is Test Bench for top_vga_mem module
//
//
// 100MHz clock input from top module
// 50% duty cycle 5ns HIGH and 5ns LOW
//`timescale [time unit] / [time precision]
`timescale 10 ns / 1ns
//sub modules
`include "clock_enable_param.v"
//top module
`include "default_reg_writer.v"
module default_reg_writer_tb();
//--------Internal register-----------
reg clk = 1'b0;
wire w_enable;
reg reset = 0;
//---------Test script----------------
// 50% duty cycle clock
always #0.5 clk <= ~clk;
//-----Unit Under test---------------
default_reg_writer uut_sender(
.clk(clk),
.i_enable(w_enable),
.i_reset(reset)
);
clock_enable_param #(
// .WAIT(WAIT),
// .WIDTH(WAIT_WIDTH)
) clock_enable1 (
.clk(clk),
.enable(w_enable)
);
initial
begin
#0_500;
$display("*");
reset = 1;
#0_020;
reset = 0;
#0_500;
$display(" ");
$display("Use this command to open timing diagram:");
$display("gtkwave -f wave.vcd");
$display("----------------------------------------------");
$finish();
end
initial
begin
$display(" ");
$display("----------------------------------------------");
$display(" Starting Testbench...");
$dumpfile("wave.vcd");
$dumpvars(0);
end
endmodule
+73
View File
@@ -0,0 +1,73 @@
module horizontal_counter #(
parameter
HSYNC_CLKS = 800,
HSYNC_DISPLAY = 640,
HSYNC_PULSE = 96,
HSYNC_FRONT_PORCH = 16,
HSYNC_BACK_PORCH = 48
)(
input clk,
output o_Hsync,
output o_h_display,
output [9:0] o_h_pixel
);
//----------Internal registers, constants and wariables-----
reg hsync_reg = 1'b1;
reg [9:0] counter_reg = 'h0;
reg [9:0] counter_pixel_reg = 'h0;
reg [2:0] r_state=HS_FRONT_PORCH, r_next=HS_FRONT_PORCH;
localparam [2:0] HS_FRONT_PORCH = 'h0,
HS_PULSE = 'h1,
HS_BACK_PORCH = 'h2,
HS_DISPLAY = 'h3;
//---------state register sequential always block-----------
always @(posedge clk ) begin
r_state <= r_next;
end
//----next state & outputs, combinational always block------
always@(posedge clk) begin
counter_reg <= counter_reg + 1;
case (r_state)
HS_FRONT_PORCH: begin
hsync_reg <= 1'b1;
if(counter_reg == HSYNC_FRONT_PORCH - 2)
r_next <= HS_PULSE;
end
HS_PULSE:begin
hsync_reg <= 1'b0;
if(counter_reg == HSYNC_FRONT_PORCH +
HSYNC_PULSE - 2)
r_next <= HS_BACK_PORCH;
end
HS_BACK_PORCH:begin
hsync_reg <= 1'b1;
if(counter_reg == HSYNC_FRONT_PORCH +
HSYNC_PULSE +
HSYNC_BACK_PORCH - 2) begin
r_next <= HS_DISPLAY;
counter_pixel_reg <= 'h0;
end
end
HS_DISPLAY:begin
hsync_reg <= 1'b1;
counter_pixel_reg <= counter_pixel_reg + 1;
if(counter_reg == HSYNC_FRONT_PORCH +
HSYNC_PULSE +
HSYNC_BACK_PORCH +
HSYNC_DISPLAY - 1) begin
r_next <= HS_FRONT_PORCH;
counter_reg <= 'h0;
end
end
endcase
end
assign o_Hsync = hsync_reg;
assign o_h_display = (counter_pixel_reg >= 1 && counter_pixel_reg <= HSYNC_DISPLAY) ? 1'b1 : 1'b0 ;
assign o_h_pixel = counter_pixel_reg - 1 ;
endmodule
+119
View File
@@ -0,0 +1,119 @@
//
// i2c sender based on VHDL code:
// http://hamsterworks.co.nz/mediawiki/index.php/OV7670_camera
//
// main input clk for module 25MHz like other
// oc7670 top module modules of my design.
//
module i2c_sender (
input clk, // 25MHz input clk
inout ov7670_sda,
output reg ov7670_scl,
output reg taken,
input send,
input [7:0] id,
input [7:0] register,
input [7:0] value);
//------------- reg/wire declarations ------------------
reg [6:0] divider = 7'b0000001; // this value gives a 127 cycle pause before the initial frame is sent
reg [31:0] busy_sr = 32'h00000000;
reg [31:0] data_sr = 32'hffffffff;
reg [15:0] r_wait = 16'h0000;
reg r_wait_done = 0;
//----------- combinational logic ----------------------
assign ov7670_sda = ( busy_sr[11:10] == 2'b10 ||
busy_sr[20:19] == 2'b10 ||
busy_sr[29:28] == 2'b10 )?
1'bz : data_sr[31];
//---------- synchronous logic -------------------------
always@(posedge clk) begin
taken <= 1'b0;
if (busy_sr[31] == 1'b0) begin
ov7670_scl <= 1'b1;
if (send == 1) begin
if (divider == 7'b0000000 && r_wait_done == 1) begin
data_sr <= {3'b100 , id , 1'b0 , register , 1'b0 , value , 1'b0 , 2'b01};
busy_sr <= {3'b111 , 9'b111111111 , 9'b111111111 , 9'b111111111 , 2'b11};
taken <= 1;
end
else begin
if (r_wait < 16'hffff) begin
r_wait <= r_wait + 1; end // this only happens on powerup
else begin
r_wait_done <= 1;
divider <= 7'b0000000;
end
end
end
end
else begin
case ({busy_sr[(32-1):(32-3)] , busy_sr[2:0]})
{3'b111,3'b111} : // start seq #1
case (divider[6 : 5])
2'b00 : ov7670_scl <= 1'b1;
2'b01 : ov7670_scl <= 1'b1;
2'b10 : ov7670_scl <= 1'b1;
default : ov7670_scl <= 1'b1;
endcase
{3'b111,3'b110} : // start seq #2
case (divider[6 : 5])
2'b00 : ov7670_scl <= 1'b1;
2'b01 : ov7670_scl <= 1'b1;
2'b10 : ov7670_scl <= 1'b1;
default : ov7670_scl <= 1'b1;
endcase
{3'b111,3'b100} : // start seq #3
case (divider[6 : 5])
2'b00 : ov7670_scl <= 1'b0;
2'b01 : ov7670_scl <= 1'b0;
2'b10 : ov7670_scl <= 1'b0;
default : ov7670_scl <= 1'b0;
endcase
{3'b110,3'b000} : // end seq #1
case (divider[6 : 5])
2'b00 : ov7670_scl <= 1'b0;
2'b01 : ov7670_scl <= 1'b1;
2'b10 : ov7670_scl <= 1'b1;
default : ov7670_scl <= 1'b1;
endcase
{3'b100,3'b000} : // end seq #2
case (divider[6 : 5])
2'b00 : ov7670_scl <= 1'b1;
2'b01 : ov7670_scl <= 1'b1;
2'b10 : ov7670_scl <= 1'b1;
default : ov7670_scl <= 1'b1;
endcase
{3'b000,3'b000} : // Idle
case (divider[6 : 5])
2'b00 : ov7670_scl <= 1'b1;
2'b01 : ov7670_scl <= 1'b1;
2'b10 : ov7670_scl <= 1'b1;
default : ov7670_scl <= 1'b1;
endcase
default :
case (divider[6 : 5])
2'b00 : ov7670_scl <= 1'b0;
2'b01 : ov7670_scl <= 1'b1;
2'b10 : ov7670_scl <= 1'b1;
default : ov7670_scl <= 1'b0;
endcase
endcase
if (divider == 7'b1111111 ) begin
busy_sr <= {busy_sr[(32-2) : 0] , 1'b0};
data_sr <= {data_sr[(32-2) : 0] , 1'b1};
divider <= 7'b0000000;
end
else begin
divider <= divider + 1;
end
end
end
endmodule
+278
View File
@@ -0,0 +1,278 @@
module imag_procesor #(
parameter CAM_DATA_WIDTH = 12,
CAM_LINE = 9,
CAM_PIXEL = 10
) (
// control signals and clk --------
input [8:0] im_p, // image processor controls
input clk,
input clk25,
input clk50,
input i_enable,
// cam2 input-----------------------
input i_we_cam2,
input [CAM_DATA_WIDTH-1:0] i_data_cam2_wr,
input [CAM_LINE-1:0] i_line_cam2,
input [CAM_PIXEL-1:0] i_pixel_cam2,
// cam1 input-----------------------
input i_we_cam1,
input [CAM_DATA_WIDTH-1:0] i_data_cam1_wr,
input [CAM_LINE-1:0] i_line_cam1,
input [CAM_PIXEL-1:0] i_pixel_cam1,
// output---------------------------
output o_we,
output [16:0] o_addr_wr,
output [CAM_DATA_WIDTH-1:0] o_data_wr,
// to register RAM for imag transform
input [24:0] i_data_reg,
output [6:0] o_addr_rd_reg
);
//------- wire for rgb2gray----------------
// cam1
wire w_we_gray_cam1;
wire [CAM_DATA_WIDTH-1:0] w_data_gray_cam1;
wire [CAM_LINE-1:0] w_line_gray_cam1;
wire [CAM_PIXEL-1:0] w_pixel_gray_cam1;
// cam2
wire w_we_gray_cam2;
wire [CAM_DATA_WIDTH-1:0] w_data_gray_cam2;
wire [CAM_LINE-1:0] w_line_gray_cam2;
wire [CAM_PIXEL-1:0] w_pixel_gray_cam2;
//------- wire for imag_transform------------
// cam1
wire w_we_it_cam1;
wire [CAM_DATA_WIDTH-1:0] w_data_it_cam1;
wire [CAM_LINE-1:0] w_line_it_cam1;
wire [CAM_PIXEL-1:0] w_pixel_it_cam1;
wire [CAM_LINE-1:0] w_imag_depth_cam1;
wire [CAM_PIXEL-1:0] w_imag_width_cam1;
wire w_imag_resized_cam1;
// cam2
wire w_we_it_cam2;
wire [CAM_DATA_WIDTH-1:0] w_data_it_cam2;
wire [CAM_LINE-1:0] w_line_it_cam2;
wire [CAM_PIXEL-1:0] w_pixel_it_cam2;
wire [CAM_LINE-1:0] w_imag_depth_cam2;
wire [CAM_PIXEL-1:0] w_imag_width_cam2;
wire w_imag_resized_cam2;
//-----------wire for reg reader module
// 1st camera
wire [CAM_PIXEL-1:0] w_cam0_WIDTH;
wire [CAM_LINE-1:0] w_cam0_DEPTH;
wire [24:0] w_cam0_T11;
wire [24:0] w_cam0_T12;
wire [24:0] w_cam0_T13;
wire [24:0] w_cam0_T21;
wire [24:0] w_cam0_T22;
wire [24:0] w_cam0_T23;
wire [24:0] w_cam0_T31;
wire [24:0] w_cam0_T32;
wire [24:0] w_cam0_T33;
// 2nd camera
wire [CAM_PIXEL-1:0] w_cam1_WIDTH;
wire [CAM_LINE-1:0] w_cam1_DEPTH;
wire [24:0] w_cam1_T11;
wire [24:0] w_cam1_T12;
wire [24:0] w_cam1_T13;
wire [24:0] w_cam1_T21;
wire [24:0] w_cam1_T22;
wire [24:0] w_cam1_T23;
wire [24:0] w_cam1_T31;
wire [24:0] w_cam1_T32;
wire [24:0] w_cam1_T33;
//---------- wire for save module -----------------
wire [CAM_DATA_WIDTH-1:0] w_o_data_sw;
wire w_o_we_sw;
wire [16:0] w_o_addr_sw;
//----------------------sub modules-------------------------------
imag_save #(
.CAM_DATA_WIDTH(CAM_DATA_WIDTH),
.CAM_LINE(CAM_LINE),
.CAM_PIXEL(CAM_PIXEL)
) imag_save(
.clk(clk),
.clk25(clk25),
.clk50(clk50),
.im_p(im_p[2:0]), // image processor controls
//input
//cam1
.i_we_cam1( w_we_it_cam1),
.i_data_cam1( w_data_it_cam1),
.i_line_cam1( w_line_it_cam1),
.i_pixel_cam1( w_pixel_it_cam1),
.i_imag_depth_cam1(w_imag_depth_cam1),
.i_imag_width_cam1(w_imag_width_cam1),
.i_imag_resized_cam1(w_imag_resized_cam1),
//cam2
.i_we_cam2( w_we_it_cam2),
.i_data_cam2( w_data_it_cam2),
.i_line_cam2( w_line_it_cam2),
.i_pixel_cam2( w_pixel_it_cam2),
.i_imag_depth_cam2(w_imag_depth_cam2),
.i_imag_width_cam2(w_imag_width_cam2),
.i_imag_resized_cam2(w_imag_resized_cam2),
//output
.o_we( w_o_we_sw),
.o_addr_wr( w_o_addr_sw),
.o_data_wr( w_o_data_sw)
);
//------------------- gray or color-------------------------------
rgb2gray #(
.CAM_DATA_WIDTH(CAM_DATA_WIDTH),
.CAM_LINE(CAM_LINE),
.CAM_PIXEL(CAM_PIXEL)
) rgb2gray_cam1(
.clk(clk),
.gray(im_p[7]), // TRUE output gray
.i_we( i_we_cam1),
.i_data_wr( i_data_cam1_wr),
.i_line( i_line_cam1),
.i_pixel( i_pixel_cam1),
.o_we( w_we_gray_cam1),
.o_data_wr( w_data_gray_cam1),
.o_line( w_line_gray_cam1),
.o_pixel( w_pixel_gray_cam1)
);
rgb2gray #(
.CAM_DATA_WIDTH(CAM_DATA_WIDTH),
.CAM_LINE(CAM_LINE),
.CAM_PIXEL(CAM_PIXEL)
) rgb2gray_cam2(
.clk(clk),
.gray(im_p[8]), // TRUE output gray
.i_we( i_we_cam2),
.i_data_wr( i_data_cam2_wr),
.i_line( i_line_cam2),
.i_pixel( i_pixel_cam2),
.o_we( w_we_gray_cam2),
.o_data_wr( w_data_gray_cam2),
.o_line( w_line_gray_cam2),
.o_pixel( w_pixel_gray_cam2)
);
//--------------------- original or transformed-------------------------
imag_transform #(
.CAM_DATA_WIDTH(CAM_DATA_WIDTH),
.CAM_LINE(CAM_LINE),
.CAM_PIXEL(CAM_PIXEL)
) imag_transform_cam1(
.clk(clk),
.im_p(im_p[4:3]), // image processor controls
//input
.i_we( w_we_gray_cam1),
.i_data( w_data_gray_cam1),
.i_line( w_line_gray_cam1),
.i_pixel( w_pixel_gray_cam1),
//output
.o_we( w_we_it_cam1),
.o_data( w_data_it_cam1),
.o_line( w_line_it_cam1),
.o_pixel( w_pixel_it_cam1),
.o_imag_depth(w_imag_depth_cam1),
.o_imag_width(w_imag_width_cam1),
.o_imag_resized(w_imag_resized_cam1),
// imag transform parmeters
.TRA_IMG_WIDTH (w_cam0_WIDTH),
.TRA_IMG_DEPTH (w_cam0_DEPTH),
.T11 (w_cam0_T11),
.T12 (w_cam0_T12),
.T13 (w_cam0_T13),
.T21 (w_cam0_T21),
.T22 (w_cam0_T22),
.T23 (w_cam0_T23),
.T31 (w_cam0_T31),
.T32 (w_cam0_T32),
.T33 (w_cam0_T33)
);
imag_transform #(
.CAM_DATA_WIDTH(CAM_DATA_WIDTH),
.CAM_LINE(CAM_LINE),
.CAM_PIXEL(CAM_PIXEL)
) imag_transform_cam2(
.clk(clk),
.im_p(im_p[6:5]), // image processor controls
//input
.i_we( w_we_gray_cam2),
.i_data( w_data_gray_cam2),
.i_line( w_line_gray_cam2),
.i_pixel( w_pixel_gray_cam2),
//output
.o_we( w_we_it_cam2),
.o_data( w_data_it_cam2),
.o_line( w_line_it_cam2),
.o_pixel( w_pixel_it_cam2),
.o_imag_depth(w_imag_depth_cam2),
.o_imag_width(w_imag_width_cam2),
.o_imag_resized(w_imag_resized_cam2),
// imag transform parmeters
.TRA_IMG_WIDTH (w_cam1_WIDTH),
.TRA_IMG_DEPTH (w_cam1_DEPTH),
.T11 (w_cam1_T11),
.T12 (w_cam1_T12),
.T13 (w_cam1_T13),
.T21 (w_cam1_T21),
.T22 (w_cam1_T22),
.T23 (w_cam1_T23),
.T31 (w_cam1_T31),
.T32 (w_cam1_T32),
.T33 (w_cam1_T33)
);
reg_reader #(
.CAM_LINE(CAM_LINE),
.CAM_PIXEL(CAM_PIXEL)
) reg_reader1 (
.clk(clk),
.i_enable(i_enable),
.i_cam0_mode(im_p[4:3]),
.i_cam1_mode(im_p[6:5]),
.i_data(i_data_reg),
.o_addr_rd(o_addr_rd_reg),
// 1st camera
.o_cam0_WIDTH(w_cam0_WIDTH),
.o_cam0_DEPTH(w_cam0_DEPTH),
.o_cam0_T11(w_cam0_T11),
.o_cam0_T12(w_cam0_T12),
.o_cam0_T13(w_cam0_T13),
.o_cam0_T21(w_cam0_T21),
.o_cam0_T22(w_cam0_T22),
.o_cam0_T23(w_cam0_T23),
.o_cam0_T31(w_cam0_T31),
.o_cam0_T32(w_cam0_T32),
.o_cam0_T33(w_cam0_T33),
// 2nd camera
.o_cam1_WIDTH(w_cam1_WIDTH),
.o_cam1_DEPTH(w_cam1_DEPTH),
.o_cam1_T11(w_cam1_T11),
.o_cam1_T12(w_cam1_T12),
.o_cam1_T13(w_cam1_T13),
.o_cam1_T21(w_cam1_T21),
.o_cam1_T22(w_cam1_T22),
.o_cam1_T23(w_cam1_T23),
.o_cam1_T31(w_cam1_T31),
.o_cam1_T32(w_cam1_T32),
.o_cam1_T33(w_cam1_T33)
);
//------------------- output logic -----------------------------------
assign o_data_wr = w_o_data_sw ;
assign o_we = w_o_we_sw ;
assign o_addr_wr = w_o_addr_sw;
endmodule
+135
View File
@@ -0,0 +1,135 @@
module imag_save #(
parameter CAM_DATA_WIDTH = 12,
CAM_LINE = 9,
CAM_PIXEL = 10
) (
input clk,
input clk25,
input clk50,
input [2:0] im_p, // image processor controls
// input form camera
//cam1
input i_we_cam1,
input [CAM_DATA_WIDTH-1:0] i_data_cam1,
input [CAM_LINE-1:0] i_line_cam1,
input [CAM_PIXEL-1:0] i_pixel_cam1,
input [CAM_LINE-1:0] i_imag_depth_cam1,
input [CAM_PIXEL-1:0] i_imag_width_cam1,
input i_imag_resized_cam1,
//cam2
input i_we_cam2,
input [CAM_DATA_WIDTH-1:0] i_data_cam2,
input [CAM_LINE-1:0] i_line_cam2,
input [CAM_PIXEL-1:0] i_pixel_cam2,
input [CAM_LINE-1:0] i_imag_depth_cam2,
input [CAM_PIXEL-1:0] i_imag_width_cam2,
input i_imag_resized_cam2,
// output
output o_we,
output [16:0] o_addr_wr,
output [CAM_DATA_WIDTH-1:0] o_data_wr
);
//------------Internal variables and constants-----------
wire w_i_we_ag;
wire [CAM_PIXEL-1:0] w_i_pixel_ag;
wire [CAM_LINE-1:0] w_i_line_ag;
wire [CAM_DATA_WIDTH-1:0] w_i_data_ag;
wire [CAM_LINE-1:0] w_imag_depth;
wire [CAM_PIXEL-1:0] w_imag_width;
wire w_imag_resized;
wire w_we_twocam;
wire [CAM_PIXEL-1:0] w_pixel_twocam;
wire [CAM_LINE-1:0] w_line_twocam;
wire [CAM_DATA_WIDTH-1:0] w_data_twocam;
wire [CAM_LINE-1:0] w_imag_depth_twocam;
wire [CAM_PIXEL-1:0] w_imag_width_twocam;
//---------------sub module--------------------------------
address_gen #(
.CAM_DATA_WIDTH(CAM_DATA_WIDTH),
.CAM_LINE(CAM_LINE),
.CAM_PIXEL(CAM_PIXEL)
) address_gen(
.clk(clk),
// input
.i_we( w_i_we_ag),
.i_data( w_i_data_ag),
.i_line( w_i_line_ag),
.i_pixel( w_i_pixel_ag),
.i_imag_depth(w_imag_depth),
.i_imag_width(w_imag_width),
// output
.o_we(o_we),
.o_data(o_data_wr),
.o_addr(o_addr_wr)
);
overlay #(
.CAM_DATA_WIDTH(CAM_DATA_WIDTH),
.CAM_LINE(CAM_LINE),
.CAM_PIXEL(CAM_PIXEL)
) overlay(
.clk(clk),
.enable(im_p[2]),
// input
.i_we(w_we_twocam ),
.i_data(w_data_twocam ),
.i_line(w_line_twocam ),
.i_pixel(w_pixel_twocam ),
.i_imag_depth(w_imag_depth_twocam ),
.i_imag_width(w_imag_width_twocam ),
.i_imag_resized( 1'b1 ),
// output
.o_we(w_i_we_ag),
.o_data(w_i_data_ag),
.o_line(w_i_line_ag),
.o_pixel(w_i_pixel_ag),
.o_imag_depth(w_imag_depth),
.o_imag_width(w_imag_width),
.o_imag_resized(w_imag_resized)
);
two_cam_one_screen #(
.CAM_DATA_WIDTH(CAM_DATA_WIDTH),
.CAM_LINE(CAM_LINE),
.CAM_PIXEL(CAM_PIXEL)
) two_cam_one_screen(
.clk1(clk25 & clk50),
.clk2(clk50 & ~clk25),
.clk( clk50 ),
.im_p(im_p[1:0]), // image processor controls
// input form camera
//cam1
.i_we_cam0(i_we_cam1),
.i_data_cam0(i_data_cam1),
.i_line_cam0(i_line_cam1),
.i_pixel_cam0(i_pixel_cam1),
.i_imag_depth_cam0(i_imag_depth_cam1),
.i_imag_width_cam0(i_imag_width_cam1),
//input i_imag_resized_cam0,
//cam2
.i_we_cam1(i_we_cam2),
.i_data_cam1(i_data_cam2),
.i_line_cam1(i_line_cam2),
.i_pixel_cam1(i_pixel_cam2),
.i_imag_depth_cam1(i_imag_depth_cam2),
.i_imag_width_cam1(i_imag_width_cam2),
//input i_imag_resized_cam1,
// output
.o_line(w_line_twocam),
.o_pixel(w_pixel_twocam),
.o_we(w_we_twocam),
.o_data_wr(w_data_twocam),
.o_imag_depth(w_imag_depth_twocam),
.o_imag_width(w_imag_width_twocam)
);
endmodule
+245
View File
@@ -0,0 +1,245 @@
module imag_transform #(
parameter CAM_DATA_WIDTH = 12,
CAM_LINE = 9,
CAM_PIXEL = 10//,
// TRA_IMG_WIDTH = 'd160,
// TRA_IMG_DEPTH = 'd160,
// T11 = 25'sb0_000000000001_011001100111,
// T12 = 25'sb0_000000000000_001011001110,
// T13 = 25'sb0_000000000000_000000001100,
// T21 = 25'sb0_000000000000_000000000000,
// T22 = 25'sb0_000000000000_111011101011,
// T23 = 25'sb0_000000000000_000000000000,
// T31 = 25'sb1_111000111111_111100111111,
// T32 = 25'sb1_111110001111_111011100000,
// T33 = 25'sb0_000000000001_000000000000
) (
input clk,
input [1:0] im_p, // image processor controls
// input form camera
input i_we,
input [CAM_DATA_WIDTH-1:0] i_data,
input [CAM_LINE-1:0] i_line,
input [CAM_PIXEL-1:0] i_pixel,
// output
output o_we,
output [CAM_DATA_WIDTH-1:0] o_data,
output [CAM_LINE-1:0] o_line,
output [CAM_PIXEL-1:0] o_pixel,
// image parameter output for address generator
output [CAM_LINE-1:0] o_imag_depth,
output [CAM_PIXEL-1:0] o_imag_width,
output o_imag_resized,
// parrameters of imag transform
input [CAM_PIXEL-1:0] TRA_IMG_WIDTH ,
input [CAM_LINE-1:0] TRA_IMG_DEPTH ,
input [24:0] T11 ,
input [24:0] T12 ,
input [24:0] T13 ,
input [24:0] T21 ,
input [24:0] T22 ,
input [24:0] T23 ,
input [24:0] T31 ,
input [24:0] T32 ,
input [24:0] T33
);
//------------Internal variables and constants-----------
(* KEEP = "TRUE" *) reg r_we1 = 0,
r_we2 = 0,
r_we3 = 0,
r_we4 = 0,
r_we5 = 0,
r_we6 = 0,
r_we7 = 0;
(* KEEP = "TRUE" *) reg [CAM_DATA_WIDTH-1:0]
r_data1 = 0,
r_data2 = 0,
r_data3 = 0,
r_data4 = 0,
r_data5 = 0,
r_data6 = 0,
r_data7 = 0;
(* KEEP = "TRUE" *) reg signed [24:0]
r_T11 = 0,
r_T12 = 0,
r_T13 = 0,
r_T21 = 0,
r_T22 = 0,
r_T23 = 0,
r_T31 = 0,
r_T32 = 0,
r_T33 = 0;
(* KEEP = "TRUE" *) wire signed [11:0] w_w_inv;
(* KEEP = "TRUE" *) reg [CAM_PIXEL-1:0] r_new_x = 0;
(* KEEP = "TRUE" *) reg [CAM_LINE-1:0] r_new_y = 0;
(* KEEP = "TRUE" *) reg signed [37:0]
r_temp_x3 = 0,
r_temp_y3 = 0;
(* KEEP = "TRUE" *) reg signed [24:0]
r_temp_w2 = 0,
r_temp_x2 = 0,
r_temp_y2 = 0;
(* KEEP = "TRUE" *) reg signed [29:0]
r_temp_x1 = 0,
r_temp_y1 = 0,
r_temp_w1 = 0;
(* KEEP = "TRUE" *) reg signed [29:0]
r_temp_summ11= 0,
r_temp_summ21= 0,
r_temp_summ31= 0;
(* KEEP = "TRUE" *) reg signed [29:0]
r_temp_summ12= 0,
r_temp_summ22= 0,
r_temp_summ32= 0;
(* KEEP = "TRUE" *) reg signed [47:0]
r_temp_11 = 0,
r_temp_12 = 0,
r_temp_13 = 0,
r_temp_21 = 0,
r_temp_22 = 0,
r_temp_23 = 0,
r_temp_31 = 0,
r_temp_32 = 0,
r_temp_33 = 0;
(* KEEP = "TRUE" *) reg signed [CAM_PIXEL:0] r_x = 0;
(* KEEP = "TRUE" *) reg signed [CAM_LINE :0] r_y = 0;
(* KEEP = "TRUE" *) reg signed [1 :0] r_w = 0;
//---------------pipeline--------------------------------
always@(posedge clk) begin
//----------------------------------7th cycle
if (r_temp_x3 < 0 || r_temp_x3[37:20] >= TRA_IMG_WIDTH) begin
r_new_x <= 0;
end else begin
r_new_x <= r_temp_x3[20+CAM_PIXEL-1:20];
end
if (r_temp_y3 < 0 || r_temp_y3[37:20] >= TRA_IMG_DEPTH) begin
r_new_y <= 0;
end else begin
r_new_y <= r_temp_y3[20 + CAM_LINE-1:20];
end
r_data7 <= r_data6;
if (r_temp_y3 < 0 || r_temp_y3[37:20] >= TRA_IMG_DEPTH ||
r_temp_x3 < 0 || r_temp_x3[37:20] >= TRA_IMG_WIDTH) begin
r_we7 <= 0;
end else begin
r_we7 <= r_we6;
end
//----------------------------------sixth cycle
r_temp_x3 <= r_temp_x2 * w_w_inv; // 35bit
r_temp_y3 <= r_temp_y2 * w_w_inv;
r_data6 <= r_data5;
r_we6 <= r_we5;
//----------------------------------- fifth cycle
r_temp_x2 <= r_temp_x1[24:0]; // resizing x value to fit 25x18bit multiplier
r_temp_y2 <= r_temp_y1[24:0]; // resizing y value to fit 25x18bit multiplier
r_temp_w2 <= r_temp_w1[24:0] ; //
r_data5 <= r_data4;
r_we5 <= r_we4;
//----------------------------------- fourth cycle
r_temp_x1 <= r_temp_summ11 + r_temp_summ12;
r_temp_y1 <= r_temp_summ21 + r_temp_summ22;
r_temp_w1 <= r_temp_summ31 + r_temp_summ32;
r_data4 <= r_data3;
r_we4 <= r_we3;
//------------------------------------third cycle
r_temp_summ11 <= r_temp_11 + r_temp_21;
r_temp_summ12 <= r_temp_31;
r_temp_summ21 <= r_temp_12 + r_temp_22;
r_temp_summ22 <= r_temp_32;
r_temp_summ31 <= r_temp_13 + r_temp_23;
r_temp_summ32 <= r_temp_33;
r_data3 <= r_data2;
r_we3 <= r_we2;
//-------------------------------------second cycle
r_temp_11 <= r_x * r_T11;
r_temp_21 <= r_y * r_T21;
r_temp_31 <= r_w * r_T31;
r_temp_12 <= r_x * r_T12;
r_temp_22 <= r_y * r_T22;
r_temp_32 <= r_w * r_T32;
r_temp_13 <= r_x * r_T13;
r_temp_23 <= r_y * r_T23;
r_temp_33 <= r_w * r_T33;
r_data2 <= r_data1;
r_we2 <= r_we1;
//-------------------------------------first cycle
r_x <= i_pixel; // saves pixel coordinates in signed register
r_y <= i_line;
r_w <= 2'sd1;
r_data1 <= i_data;
r_we1 <= i_we;
r_T11 <= T11;
r_T12 <= T12;
r_T13 <= T13;
r_T21 <= T21;
r_T22 <= T22;
r_T23 <= T23;
r_T31 <= T31;
r_T32 <= T32;
r_T33 <= T33;
//-------------------------------------
// matrix multiplication and new point coordinate calculation
//
// | T11 T12 T13 |
// P [x,y,1] * T [3x3] = | x y 1 | * | T21 T22 T23 | = | x' y' w' |
// | T31 T32 T33 |
// | x' y'|
// Pnew [x'',y''] = |---,---|
// | w' w'|
end
//--------------------sub module------------------------
lookuptable lookuptable(
.clk(clk),
.w(r_temp_w2[15:4]), // inputs calculated w value
.r_w_inv(w_w_inv) // outputs inverted value from look up table
);
//------------ output logic------------------------------
// assign o_we = (im_p == 2'b00)? i_we : r_we7;
// assign o_data = (im_p == 2'b00)? i_data : r_data7;
//
// assign o_line = (im_p == 2'b00)? i_line : r_new_y;
// assign o_pixel = (im_p == 2'b00)? i_pixel: r_new_x;
//
//
// assign o_imag_depth = (im_p == 2'b00)? 'd480 : TRA_IMG_DEPTH;
// assign o_imag_width = (im_p == 2'b00)? 'd640 : TRA_IMG_WIDTH;
// assign o_imag_resized = (im_p == 2'b00)? 1'b0 : 1'b1;
// output always resized and unsing transformation matrix.
assign o_we = r_we7;
assign o_data = r_data7;
assign o_line = r_new_y;
assign o_pixel = r_new_x;
assign o_imag_depth = TRA_IMG_DEPTH;
assign o_imag_width = TRA_IMG_WIDTH;
assign o_imag_resized = 1'b1;
endmodule
+78
View File
@@ -0,0 +1,78 @@
// This file is Test Bench for top_vga_mem module
//
//
// 100MHz clock input from top module
// 50% duty cycle 5ns HIGH and 5ns LOW
//`timescale [time unit] / [time precision]
`timescale 10 ns / 1ns
//sub modules
`include "imag_transform.v"
//top module
`include "lookuptable.v"
module imag_transform_tb#(
parameter CAM_DATA_WIDTH = 12,
CAM_LINE = 9,
CAM_PIXEL = 10
)();
//--------Internal register-----------
reg clk = 1'b0;
reg [CAM_LINE-1:0] r_line_cam = 0;
reg [CAM_PIXEL-1:0] r_pixel_cam = 0;
wire [CAM_LINE-1:0] r_line_out ;
wire [CAM_PIXEL-1:0] r_pixel_out ;
//---------Test script----------------
// 50% duty cycle clock
always #0.5 clk <= ~clk;
//-----Unit Under test---------------
imag_transform #(
.CAM_DATA_WIDTH(CAM_DATA_WIDTH),
.CAM_LINE(CAM_LINE),
.CAM_PIXEL(CAM_PIXEL)
) test_module (
.clk(clk),
.i_we(1'b1),
.i_data(12'h0f0),
.im_p(2'b01),
.i_line(r_line_cam),
.i_pixel(r_pixel_cam),
.o_line(r_line_out),
.o_pixel(r_pixel_out)
);
initial
begin
#0_000;
r_line_cam = 'd203;
r_pixel_cam = 'd403;
#0_010;
r_line_cam = 'd250;
r_pixel_cam = 'd470;
#0_010;
r_line_cam = 'd40;
r_pixel_cam = 'd120;
#0_010;
$display(" ");
$display("Use this command to open timing diagram:");
$display("gtkwave -f wave.vcd");
$display("----------------------------------------------");
$finish();
end
initial
begin
$display(" ");
$display("----------------------------------------------");
$display(" Starting Testbench...");
$dumpfile("wave.vcd");
$dumpvars(0);
end
endmodule
+1431
View File
File diff suppressed because it is too large Load Diff
+109
View File
@@ -0,0 +1,109 @@
module ov7670_capture #(
parameter CAM_DATA_WIDTH = 12,
CAM_LINE = 9,
CAM_PIXEL = 10
)(
output we,
output [CAM_DATA_WIDTH-1:0] o_data_wr,
output [CAM_LINE-1:0] o_line,
output [CAM_PIXEL-1:0] o_pixel,
input reset,
input ov7670_pclk,
input ov7670_vs,
input ov7670_hs,
input [7:0] ov7670_data
);
//-----------internal regiters and wires-----------------
reg [1:0] pixel_counter = 'h0;
/* // YUV grayscale mode
reg [7:0] u; // U=B-Y
reg [7:0] v; // V=R-Y
reg [7:0] y0; // Y=0.59G + 0.31R + 0.11B
reg [7:0] y1; // Y=0.59G + 0.31R + 0.11B
*/
// Color mode RGB 565
reg [7:0] byte1 = 'h0;
reg [7:0] byte2 = 'h0;
reg [7:0] byte3 = 'h0;
reg [7:0] byte4 = 'h0;
reg [CAM_LINE-1:0] line = 'h0;
reg [CAM_PIXEL-1:0] pixel = 'h0;
reg vsync_old_reg = 'h0;
reg hsync_old_reg = 'h0;
//-------------------------------------------------------
always@(posedge ov7670_pclk)begin
vsync_old_reg <= ov7670_vs;
hsync_old_reg <= ov7670_hs;
end
//-------------------------------------------------------
always@(posedge ov7670_pclk || reset)begin
if (ov7670_hs== 0 || reset == 1) begin
pixel_counter <= 0;
end
if (ov7670_hs == 1 && ov7670_vs== 0 ) begin
case (pixel_counter)
/* // YUV grayscale mode
2'b00: u <= ov7670_data;
2'b01: y0 <= ov7670_data;
2'b10: v <= ov7670_data;
2'b11: y1 <= ov7670_data;
*/ // RGB color mode
2'b00: byte1 <= ov7670_data;
2'b01: byte2 <= ov7670_data;
2'b10: byte3 <= ov7670_data;
2'b11: byte4 <= ov7670_data;
endcase
if ( pixel_counter[0] == 1 ) begin
if (pixel < 639 )
pixel <= pixel +1;
end
pixel_counter <= pixel_counter + 1;
end
if(hsync_old_reg==1 && ov7670_hs==0) begin
pixel <= 0;
line <= line + 1;
end
if(vsync_old_reg==1 && ov7670_vs == 0) begin
line <= 0;
end
end
assign o_pixel = pixel;//[9:1];
assign o_line = line;//[8:1];
assign we = (pixel_counter[0]==1'b1) ? 1'b1 : 1'b0;
//assign we = (pixel_counter==2'b11) ? 1'b1 : 1'b0;
// -------------- grayscale image from YUV ------------------------
/*
assign o_data_wr = {y0[7:4],
y0[7:4],
y0[7:4]
};
*/
//--------------- color RGB mode ---------------------------------
assign o_data_wr = pixel_counter[1] ?
{ byte1[7:4],
{ byte1[2:0],byte2[7] },
byte2[4:1]
}
:
{ byte3[7:4],
{ byte3[2:0],byte4[7] },
byte4[4:1]
};
endmodule
+45
View File
@@ -0,0 +1,45 @@
module ov7670_controller (
input clk, // 25MHz input clk
inout ov7670_sda,
output ov7670_scl,
input resend,
output config_finished,
output ov7670_pwdn,
output ov7670_reset,
output ov7670_mclk );
//--------------wires and registers----------------------
wire [15:0] command;
wire finished;
wire taken;
localparam CAMERA_ADDR = 8'h42; // or 8'h21
//------------controls of camera-------------------------
assign ov7670_reset = 1'b1; // Normal mode
assign ov7670_pwdn = 1'b0; // Power device up
assign ov7670_mclk = clk;
assign config_finished = finished;
//-----------sub modules---------------------------------
i2c_sender i2c_sender (
.clk(clk),
.ov7670_sda(ov7670_sda),
.ov7670_scl(ov7670_scl),
.taken(taken),
.send(~finished),
.id(CAMERA_ADDR),
.register(command[15:8]),
.value(command[7:0]) );
ov7670_registers ov7670_registers (
.clk(clk),
.resend(resend),
.advance(taken),
.command(command),
.finished(finished) );
endmodule
+331
View File
@@ -0,0 +1,331 @@
// VHDL code: http://hamsterworks.co.nz/mediawiki/index.php/OV7670_camera
//
// Description: Register settings for the OV7670 Caamera (partially from OV7670.c
// in the Linux Kernel
//
module ov7670_registers(
input clk, //: in STD_LOGIC;
input resend, //: in STD_LOGIC;
input advance, //: in STD_LOGIC;
output [15:0] command, //: out std_logic_vector(15 downto 0);
output finished //: out STD_LOGIC
);
reg [15:0] sreg; // : std_logic_vector(15 downto 0);
reg [8:0] address = 'h0; //: std_logic_vector(7 downto 0) := (others => '0');
reg r_resend_old = 0;
always@(posedge clk) begin
r_resend_old <= resend;
end
always@(posedge clk) begin
if (r_resend_old == 1 && resend == 0 ) begin
address <= 'h0;
end
else if (advance == 1) begin
address <= address + 1;
end
case (address)
// // new settings
// 8'h00 : sreg <= 16'h1280; // COM7 Reset
// 8'h01 : sreg <= 16'h1280; // COM7 Reset
// 8'h02 : sreg <= 16'h1204; // COM7 Size & RGB output
// 8'h03 : sreg <= 16'h1100; // CLKRC Prescaler - Fin/(1+1)
// 8'h04 : sreg <= 16'h0C00; // COM3 Lots of stuff, enable scaling, all others off
// 8'h05 : sreg <= 16'h3E00; // COM14 PCLK scaling off
// 8'h06 : sreg <= 16'h8C00; // RGB444 Set RGB format
// 8'h07 : sreg <= 16'h0400; // COM1 no CCIR601
// 8'h08 : sreg <= 16'h4010; // COM15 Full 0-255 output, RGB 565
// 8'h09 : sreg <= 16'h3a04; // TSLB Set UV ordering, do not auto-reset window
// 8'h0A : sreg <= 16'h1438; // COM9 - AGC Celling
// 8'h0B : sreg <= 16'h4fb3; // MTX1 - colour conversion matrix
// 8'h0C : sreg <= 16'h50b3; // MTX2 - colour conversion matrix
// 8'h0D : sreg <= 16'h5100; // MTX3 - colour conversion matrix
// 8'h0E : sreg <= 16'h523d; // MTX4 - colour conversion matrix
// 8'h0F : sreg <= 16'h53a7; // MTX5 - colour conversion matrix
// 8'h10 : sreg <= 16'h54e4; // MTX6 - colour conversion matrix
// 8'h11 : sreg <= 16'h589e; // MTXS - Matrix sign and auto contrast
// 8'h12 : sreg <= 16'h3dc0; // COM13 - Turn on GAMMA and UV Auto adjust
// 8'h13 : sreg <= 16'h1100; // CLKRC Prescaler - Fin/(1+1)
// 8'h14 : sreg <= 16'h1713; // HSTART HREF start (high 8 bits)
// 8'h15 : sreg <= 16'h1801; // HSTOP HREF stop (high 8 bits)
// 8'h16 : sreg <= 16'h32b6; // HREF Edge offset and low 3 bits of HSTART and HSTOP
// 8'h17 : sreg <= 16'h1902; // VSTART VSYNC start (high 8 bits)
// 8'h18 : sreg <= 16'h1A7a; // VSTOP VSYNC stop (high 8 bits)
// 8'h19 : sreg <= 16'h030a; // VREF VSYNC low two bits
// 8'h1A : sreg <= 16'h0e61; // COM5(0x0E) 0x61
// 8'h1B : sreg <= 16'h0f4b; // COM6(0x0F) 0x4B
// 8'h1C : sreg <= 16'h1602; //
// 8'h1D : sreg <= 16'h1e37; // MVFP (0x1E) 0x07 -- FLIP AND MIRROR IMAGE 0x3x
// 8'h1E : sreg <= 16'h2102;
// 8'h1F : sreg <= 16'h2291;
// 8'h20 : sreg <= 16'h2907;
// 8'h21 : sreg <= 16'h330b;
// 8'h22 : sreg <= 16'h350b;
// 8'h23 : sreg <= 16'h371d;
// 8'h24 : sreg <= 16'h3871;
// 8'h25 : sreg <= 16'h392a;
// 8'h26 : sreg <= 16'h3c78; // COM12 (0x3C) 0x78
// 8'h27 : sreg <= 16'h4d40;
// 8'h28 : sreg <= 16'h4e20;
// 8'h29 : sreg <= 16'h6900; // GFIX (0x69) 0x00
// 8'h2A : sreg <= 16'h6b4a;
// 8'h2B : sreg <= 16'h7410;
// 8'h2C : sreg <= 16'h8d4f;
// 8'h2D : sreg <= 16'h8e00;
// 8'h2E : sreg <= 16'h8f00;
// 8'h2F : sreg <= 16'h9000;
// 8'h30 : sreg <= 16'h9100;
// 8'h31 : sreg <= 16'h9600;
// 8'h32 : sreg <= 16'h9a00;
// 8'h33 : sreg <= 16'hb084;
// 8'h34 : sreg <= 16'hb10c;
// 8'h35 : sreg <= 16'hb20e;
// 8'h36 : sreg <= 16'hb382;
// 8'h37 : sreg <= 16'hb80a;
// // settings added by me
// 8'h38 : sreg <= 16'h13e7; // enable AWB from sw aplication notes
// 8'h39 : sreg <= 16'h6f9f; // Simple White Balance from sw aplication notes
// 8'h40 : sreg <= 16'h411A; // De-noise auto-adjustment + AWB gain enable + Color matrix coefficient double option 0: Original matrix
// 8'h41 : sreg <= 16'h7700; // Register 77 Bit[7:0]:Offset, de-noise range control
// // old settings
8'd00 : sreg <= 16'h1280; // COM7 Reset
8'd01 : sreg <= 16'h1280; // COM7 Reset
8'd02 : sreg <= 16'h1204; // COM7 Size & RGB output
8'd03 : sreg <= 16'h1100; // CLKRC Prescaler - Fin/(1+1)
8'd04 : sreg <= 16'h0C00; // COM3 Lots of stuff, enable scaling, all others off
8'd05 : sreg <= 16'h3E00; // COM14 PCLK scaling off
8'd06 : sreg <= 16'h8C00; // RGB444 Set RGB format
8'd07 : sreg <= 16'h0400; // COM1 no CCIR601
8'd08 : sreg <= 16'h4010; // COM15 Full 0-255 output, RGB 565
8'd09 : sreg <= 16'h3a04; // TSLB Set UV ordering, do not auto-reset window
8'd10 : sreg <= 16'h1438; // COM9 - AGC Celling
8'd11 : sreg <= 16'h4fb3; // MTX1 - colour conversion matrix
8'd12 : sreg <= 16'h50b3; // MTX2 - colour conversion matrix
8'd13 : sreg <= 16'h5100; // MTX3 - colour conversion matrix
8'd14 : sreg <= 16'h523d; // MTX4 - colour conversion matrix
8'd15 : sreg <= 16'h53a7; // MTX5 - colour conversion matrix
8'd16 : sreg <= 16'h54e4; // MTX6 - colour conversion matrix
8'd17 : sreg <= 16'h581e; // 16'h589e; // MTXS - Matrix sign and auto contrast
8'd18 : sreg <= 16'h3dc0; // COM13 - Turn on GAMMA and UV Auto adjust
8'd19 : sreg <= 16'h1713; // HSTART HREF start (high 8 bits)
8'd20 : sreg <= 16'h1801; // HSTOP HREF stop (high 8 bits)
8'd21 : sreg <= 16'h32b6; // HREF Edge offset and low 3 bits of HSTART and HSTOP
8'd22 : sreg <= 16'h1902; // VSTART VSYNC start (high 8 bits)
8'd23 : sreg <= 16'h1A7a; // VSTOP VSYNC stop (high 8 bits)
8'd24 : sreg <= 16'h030a; // VREF VSYNC low two bits
//
// 8'd26 : sreg <= 16'h0e61; // COM5(0x0E) 0x61
// 8'd27 : sreg <= 16'h0f4b; // COM6(0x0F) 0x4B
// 8'd28 : sreg <= 16'h1602; //
// 8'd29 : sreg <= 16'h1e37; // MVFP (0x1E) 0x07 // FLIP AND MIRROR IMAGE 0x3x
// 8'd30 : sreg <= 16'h2102;
// 8'd31 : sreg <= 16'h2291;
// 8'd32 : sreg <= 16'h2907;
// 8'd33 : sreg <= 16'h330b;
// 8'd34 : sreg <= 16'h350b;
// 8'd35 : sreg <= 16'h371d;
// 8'd36 : sreg <= 16'h3871;
// 8'd37 : sreg <= 16'h392a;
// 8'd26 : sreg <= 16'h3c78;
//
// 8'd38 : sreg <= 16'h3c78; // COM12 (0x3C) 0x78
// 8'd39 : sreg <= 16'h4d40;
// 8'd40 : sreg <= 16'h4e20;
// 8'd41 : sreg <= 16'h6900; // GFIX (0x69) 0x00
// 8'd42 : sreg <= 16'h6b4a;
// 8'd43 : sreg <= 16'h7410;
// 8'd44 : sreg <= 16'h8d4f;
// 8'd45 : sreg <= 16'h8e00;
// 8'd26 : sreg <= 16'h8f00;
// 8'd27 : sreg <= 16'h9000;
//
8'd25 : sreg <= 16'h9100;
8'd26 : sreg <= 16'h9600;
8'd27 : sreg <= 16'h9a00;
8'd28 : sreg <= 16'hb084;
8'd29 : sreg <= 16'hb10c;
8'd30 : sreg <= 16'hb20e;
8'd31 : sreg <= 16'hb382;
8'd32 : sreg <= 16'hb80a;
// setings form fpga4students
// 8'd00 : sreg <= 16'h1280; // COM7 Reset
// 8'd01 : sreg <= 16'h1280; // COM7 Reset
// 8'd02 : sreg <= 16'h1206; // COM7 Size & RGB output
// // 8'd03 : sreg <= 16'h1100; // CLKRC Prescaler - Fin/(1+1)
// // 8'd04 : sreg <= 16'h0C00; // COM3 Lots of stuff, enable scaling, all others off
// // 8'h05 : sreg <= 16'h3E00; // COM14 PCLK scaling off
// 8'd06 : sreg <= 16'h8C00; // RGB444 Set RGB format
// // 8'd07 : sreg <= 16'h0400; // COM1 no CCIR601
// // 8'd08 : sreg <= 16'h4010; // COM15 Full 0-255 output, RGB 565
// // 8'd09 : sreg <= 16'h3a04; // TSLB Set UV ordering, do not auto-reset window
// // 8'd10 : sreg <= 16'h1438; // COM9 - AGC Celling
// // // 8'h0B : sreg <= 16'h4fb3; // MTX1 - colour conversion matrix
// // // 8'h0C : sreg <= 16'h50b3; // MTX2 - colour conversion matrix
// // // 8'd11 : sreg <= 16'h5100; // MTX3 - colour conversion matrix
// // // 8'd11 : sreg <= 16'h523d; // MTX4 - colour conversion matrix
// // // 8'h0F : sreg <= 16'h53a7; // MTX5 - colour conversion matrix
// // // 8'h10 : sreg <= 16'h54e4; // MTX6 - colour conversion matrix
// // // 8'd11 : sreg <= 16'h589e; // MTXS - Matrix sign and auto contrast
// // 8'd11 : sreg <= 16'h3dc0; // COM13 - Turn on GAMMA and UV Auto adjust
// // 8'd12 : sreg <= 16'h1100; // CLKRC Prescaler - Fin/(1+1)
// 8'd13 : sreg <= 16'h1713; // HSTART HREF start (high 8 bits)
// 8'd14 : sreg <= 16'h1801; // HSTOP HREF stop (high 8 bits)
// 8'd15 : sreg <= 16'h32b6; // HREF Edge offset and low 3 bits of HSTART and HSTOP
// 8'd16 : sreg <= 16'h1902; // VSTART VSYNC start (high 8 bits)
// 8'd17 : sreg <= 16'h1A7a; // VSTOP VSYNC stop (high 8 bits)
// 8'd18 : sreg <= 16'h030a; // VREF VSYNC low two bits
// // 8'h1A : sreg <= 16'h0e61; // COM5(0x0E) 0x61
// // 8'h1B : sreg <= 16'h0f4b; // COM6(0x0F) 0x4B
// // 8'h1C : sreg <= 16'h1602; //
// // 8'h1D : sreg <= 16'h1e37; // MVFP (0x1E) 0x07 // FLIP AND MIRROR IMAGE 0x3x
// // 8'h1E : sreg <= 16'h2102;
// // 8'h1F : sreg <= 16'h2291;
// // 8'h20 : sreg <= 16'h2907;
// // 8'h21 : sreg <= 16'h330b;
// // 8'h22 : sreg <= 16'h350b;
// // 8'h23 : sreg <= 16'h371d;
// // 8'h24 : sreg <= 16'h3871;
// // 8'h25 : sreg <= 16'h392a;
// // 8'h26 : sreg <= 16'h3c78; // COM12 (0x3C) 0x78
// // 8'h27 : sreg <= 16'h4d40;
// // 8'h28 : sreg <= 16'h4e20;
// // 8'h29 : sreg <= 16'h6900; // GFIX (0x69) 0x00
// // 8'h2A : sreg <= 16'h6b4a;
// // 8'h2B : sreg <= 16'h7410;
// // 8'h2C : sreg <= 16'h8d4f;
// // 8'h2D : sreg <= 16'h8e00;
// // 8'h2E : sreg <= 16'h8f00;
// // 8'h2F : sreg <= 16'h9000;
// // 8'h30 : sreg <= 16'h9100;
// // 8'h31 : sreg <= 16'h9600;
// // 8'h32 : sreg <= 16'h9a00;
// // 8'h33 : sreg <= 16'hb084;
// // 8'h34 : sreg <= 16'hb10c;
// // 8'h35 : sreg <= 16'hb20e;
// // 8'h36 : sreg <= 16'hb382;
// // 8'h37 : sreg <= 16'hb80a;
// // settings added by me
// 8'd19 : sreg <= 16'h13e7; // enable AWB from sw aplication notes
// 8'd20 : sreg <= 16'h6f9f; // Simple White Balance from sw aplication notes
// 8'd21 : sreg <= 16'h411A; // De-noise auto-adjustment + AWB gain enable + Color matrix coefficient double option 0: Original matrix
// 8'd22 : sreg <= 16'h7700; // Register 77 Bit[7:0]:Offset, de-noise range control
// // Saturation + 2
// // i2c_salve_Address = 0x42;
// // write_i2c(0x4f, 0xc0);
// // write_i2c(0x50, 0xc0);
// // write_i2c(0x51, 0x00);
// // write_i2c(0x52, 0x33);
// // write_i2c(0x53, 0x8d);
// // write_i2c(0x54, 0xc0);
// // write_i2c(0x58, 0x9e);
// 8'd23 : sreg <= 16'h4fb3; // MTX1 - colour conversion matrix
// 8'd24 : sreg <= 16'h50b3; // MTX2 - colour conversion matrix
// 8'd25 : sreg <= 16'h5100; // MTX3 - colour conversion matrix
// 8'd26 : sreg <= 16'h523d; // MTX4 - colour conversion matrix
// 8'd27 : sreg <= 16'h53a7; // MTX5 - colour conversion matrix
// 8'd28 : sreg <= 16'h54e4; // MTX6 - colour conversion matrix
// 8'd29 : sreg <= 16'h589e; // MTXS - Matrix sign and auto contrast
// // setings from : http://hamsterworks.co.nz/mediawiki/index.php/OV7670_camera
// 8'h00 : sreg <= 16'h1280; //COM7 Reset
// 8'h01 : sreg <= 16'h1280; //COM7 Reset
// 8'h02 : sreg <= 16'h1100; //CLKRC Prescaler - Fin/(1+1)
// 8'h03 : sreg <= 16'h1204; //COM7 QIF + RGB output
// 8'h04 : sreg <= 16'h0C04; //COM3 Lots of stuff, enable scaling, all others off
// 8'h05 : sreg <= 16'h3E19; //COM14 PCLK scaling = 0
// 8'h06 : sreg <= 16'h4010; //COM15 Full 0-255 output, RGB 565
// 8'h07 : sreg <= 16'h3a04; //TSLB Set UV ordering, do not auto-reset window
// 8'h08 : sreg <= 16'h8C00; //RGB444 Set RGB format
// 8'h09 : sreg <= 16'h1714; //HSTART HREF start (high 8 bits)
// 8'h0a : sreg <= 16'h1802; //HSTOP HREF stop (high 8 bits)
// 8'h0b : sreg <= 16'h32A4; //HREF Edge offset and low 3 bits of HSTART and HSTOP
// 8'h0c : sreg <= 16'h1903; //VSTART VSYNC start (high 8 bits)
// 8'h0d : sreg <= 16'h1A7b; //VSTOP VSYNC stop (high 8 bits)
// 8'h0e : sreg <= 16'h030a; //VREF VSYNC low two bits
// 8'h0f : sreg <= 16'h703a; //SCALING_XSC
// 8'h10 : sreg <= 16'h7135; //SCALING_YSC
// 8'h11 : sreg <= 16'h7211; //SCALING_DCWCTR
// 8'h12 : sreg <= 16'h73f1; //SCALING_PCLK_DIV
// 8'h13 : sreg <= 16'ha202; //SCALING_PCLK_DELAY PCLK scaling = 4, must match COM14
default : sreg <= 16'hffff;
endcase;
end
assign command = sreg;
assign finished = (sreg == 16'hffff) ? 1'b1 : 1'b0;
endmodule
+65
View File
@@ -0,0 +1,65 @@
module ov7670_top #(
parameter CAM_DATA_WIDTH = 12,
CAM_LINE = 9,
CAM_PIXEL = 10
)(
input clk, // 25MHz clk
output [CAM_DATA_WIDTH-1:0] o_data_wr,
output we,
output [CAM_LINE-1:0] o_line,
output [CAM_PIXEL-1:0] o_pixel,
output config_finished,
input btn,
input ov7670_pclk,
output ov7670_mclk,
input ov7670_vs,
input ov7670_hs,
input [7:0] ov7670_data,
output ov7670_scl,
inout ov7670_sda,
output ov7670_pwdn,
output ov7670_reset
);
//-----------internal regiters and wires-----------------
wire resend;
wire w_finished;
//---------------sub modules--------------------------
debounce_switch debounce_switch(
.clk(clk),
.i_switch(btn),
.o_switch(btn_db));
ov7670_capture #(
.CAM_DATA_WIDTH(CAM_DATA_WIDTH),
.CAM_LINE(CAM_LINE),
.CAM_PIXEL(CAM_PIXEL)
) ov7670_capture (
.we(we),
.reset(btn_db),
.o_data_wr(o_data_wr),
.o_line(o_line),
.o_pixel(o_pixel),
.ov7670_pclk(ov7670_pclk),
.ov7670_vs(ov7670_vs),
.ov7670_hs(ov7670_hs),
.ov7670_data(ov7670_data)
);
ov7670_controller ov7670_controller (
.clk(clk),
.ov7670_sda(ov7670_sda),
.ov7670_scl(ov7670_scl),
.resend(btn_db),
.config_finished(config_finished),
.ov7670_pwdn(ov7670_pwdn),
.ov7670_reset(ov7670_reset),
.ov7670_mclk(ov7670_mclk) );
endmodule
+122
View File
@@ -0,0 +1,122 @@
// This file is Test Bench for top_vga_mem module
//
//
// 25MHz clock input from top module
// 50% duty cycle 20ns HIGH and 20ns LOW
//`timescale [time unit] / [time precision]
`timescale 10 ns / 10ns
//sub modules
`include "i2c_senderv2.v"
`include "debounce_switch.v"
`include "ov7670_capture.v"
`include "ov7670_registers.v"
`include "ov7670_controller.v"
//top module
`include "ov7670_top.v"
module ov7670_top_tb();
//--------Internal register-----------
reg clk = 1'b0;
reg reset = 1'b0;
reg send_enable = 1'b0;
// bidirectional test bench
// source:
// https://stackoverflow.com/questions/31391112/bidirectional-port-in-verilog-testbench
wire input_value;
wire bidir_signal;
reg output_value;
reg output_value_valid;
reg btn_reg=0;
assign input_value = bidir_signal;
assign bidir_signal = (output_value_valid==1'b1)? output_value : 1'hZ;
//---------Test script----------------
// 50% duty cycle clock
always #2 clk <= ~clk;
//-----Unit Under test---------------
ov7670_top #(
)Test_Unit(
.clk(clk),
.btn(btn_reg),
.ov7670_pclk(),
.ov7670_mclk(),
.ov7670_vs(),
.ov7670_hs(),
.ov7670_data(),
.ov7670_scl(),
.ov7670_sda(bidir_signal),
.ov7670_pwdn(),
.ov7670_reset()
);
// first ACK signal
initial
begin
#0 output_value = 0;
output_value_valid = 0;
#8902 output_value = 0;
output_value_valid = 0;
#600 output_value = 0;
output_value_valid = 0;
end
// second ACK signal
initial
begin
#16_102 output_value = 0;
output_value_valid = 0;
#600 output_value = 0;
output_value_valid = 0;
end
// therd ACK signal
initial
begin
#23_302 output_value = 0;
output_value_valid = 0;
#600 output_value = 0;
output_value_valid = 0;
end
initial
begin
#0 btn_reg = 0;
#10_000 btn_reg = 1;
#10000 btn_reg = 0;
#50000;
$display("*");
#0 btn_reg = 0;
#10_000 btn_reg = 1;
#20000000 btn_reg = 0;
#5000000;
$display("*");
$display("Use this command to open timing diagram:");
$display("gtkwave -f wave.vcd");
$display("----------------------------------------------");
$finish();
end
initial
begin
$display(" ");
$display("----------------------------------------------");
$display(" Starting Testbench...");
$dumpfile("wave.vcd");
$dumpvars(0);
end
endmodule
+110
View File
@@ -0,0 +1,110 @@
module overlay #(
parameter CAM_DATA_WIDTH = 12,
CAM_LINE = 9,
CAM_PIXEL = 10
) (
input clk,
input enable,
// input form camera
input i_we,
input [CAM_DATA_WIDTH-1:0] i_data,
input [CAM_LINE-1:0] i_line,
input [CAM_PIXEL-1:0] i_pixel,
// image size and does it need to be resized
input [CAM_LINE-1:0] i_imag_depth,
input [CAM_PIXEL-1:0] i_imag_width,
input i_imag_resized,
output [CAM_LINE-1:0] o_imag_depth,
output [CAM_PIXEL-1:0] o_imag_width,
output o_imag_resized,
// output
output o_we,
output [CAM_DATA_WIDTH-1:0] o_data,
output [CAM_LINE-1:0] o_line,
output [CAM_PIXEL-1:0] o_pixel
);
//------------Internal variables and constants-----------
reg [CAM_LINE-1:0] r_line = 0;
reg [CAM_PIXEL-1:0] r_pixel = 0;
reg [CAM_DATA_WIDTH-1:0] r_data = 0;
reg r_we = 0;
//------------ syncronus logic----------------------------
always@(posedge clk) begin
if(i_imag_resized) begin
if (enable) begin
if (i_line == 40 ||
i_line == 80 ||
i_line == 120 ||
i_line == 160 ||
i_line == 200 ||
i_pixel == 40 ||
i_pixel == 80 ||
i_pixel == 120 ||
i_pixel == 160 ||
i_pixel == 200 ||
i_pixel == 240 ||
i_pixel == 280 ) begin
r_line <= i_line;
r_pixel <= i_pixel;
r_data <= 12'h0f0;
r_we <= i_we;
end else begin
r_line <= i_line;
r_pixel <= i_pixel;
r_data <= i_data;
r_we <= i_we;
end
end else begin
r_line <= i_line;
r_pixel <= i_pixel;
r_data <= i_data;
r_we <= i_we;
end
end
else begin
if (enable) begin
if (i_line == 80 ||
i_line == 160 ||
i_line == 240 ||
i_line == 320 ||
i_line == 400 ||
i_pixel == 80 ||
i_pixel == 160 ||
i_pixel == 240 ||
i_pixel == 320 ||
i_pixel == 400 ||
i_pixel == 480 ||
i_pixel == 560
) begin
r_line <= i_line;
r_pixel <= i_pixel;
r_data <= 12'h0f0;
r_we <= i_we;
end else begin
r_line <= i_line;
r_pixel <= i_pixel;
r_data <= i_data;
r_we <= i_we;
end
end else begin
r_line <= i_line;
r_pixel <= i_pixel;
r_data <= i_data;
r_we <= i_we;
end
end
end
//------------ output logic -----------------------------
assign o_we = r_we;
assign o_line = r_line;
assign o_pixel = r_pixel;
assign o_data = r_data;
assign o_imag_depth = i_imag_depth;
assign o_imag_width = i_imag_width;
assign o_imag_resized = i_imag_resized;
endmodule
+150
View File
@@ -0,0 +1,150 @@
// This module generates color patherns and rwite them in
// BlockRAM memory
//
module pattern_gen #( parameter
LINES = 480,
COLUMNS = 640,
DEPTH = 76_800, //307_200, //
ADDR_WIDTH = 17,
DATA_WIDTH = 12,
SPEED = 2,
SIZE = 2
)(
input clk,
input i_enable,
// input sw,
output [ADDR_WIDTH-1:0] o_addr,
output [DATA_WIDTH-1:0] o_data,
output o_write);
//-------------Internal Constants---------------------------
//reg [ADDR_WIDTH-1:0] counter_reg = 'b0;
reg [31:0] speed_counter_reg = 'b0;
//reg [DATA_WIDTH-1:0] color_reg = 'b0;
reg [3:0] red_reg = 'b0;
reg [3:0] blue_reg = 'b0;
reg [3:0] green_reg = 'b0;
reg [8:0] line_reg = 'b0;
reg [9:0] column_reg = 'b0;
reg write_reg=1'b0;
/*
localparam [SIZE-1:0] GREEN = 'h0,
RED = 'h1,
BLUE = 'h2;
reg [SIZE-1:0] state_reg=GREEN, next_reg=GREEN;
//---------state register sequential always block-----------
always @(posedge clk ) begin
if (i_enable) begin
state_reg <= next_reg;
end
end
*/
//----next state & outputs, combinational always block------
always @(posedge clk) begin
speed_counter_reg <= speed_counter_reg + 1;
if(speed_counter_reg == SPEED) begin
write_reg <= 1'b1;
speed_counter_reg <= 0;
if(i_enable) begin
// counter_reg <= counter_reg + 1;
if(column_reg < COLUMNS-1) begin
column_reg <= column_reg + 1 ;
end
else begin
column_reg <= 0;
if (line_reg< LINES -1 ) begin
line_reg <= line_reg + 1;
end
else begin
line_reg <= 0;
end
end
/*
if (line_reg < 239 ) begin
green_reg <= 4'b1111;
end
else begin
green_reg <= 4'b0000;
end
*/
/*
if (column_reg < 319 || column_reg == 639) begin
red_reg <= 4'b1111;
end
else begin
red_reg <= 4'b0000;
end
*/
/*
case (state_reg)
GREEN : begin
color_reg <= 12'b111100000000;
if(counter_reg == DEPTH - 1) begin
next_reg <= RED;
counter_reg <= 'b0;
end
end
RED : begin
color_reg <= 12'b000011110000;
if(counter_reg == DEPTH - 1 ) begin
next_reg <= BLUE;
counter_reg <= 'b0;
end
end
BLUE : begin
color_reg <= 12'b000000001111;
if(counter_reg == DEPTH - 1) begin
next_reg <= GREEN;
counter_reg <= 'b0;
end
end
default: begin
next_reg <= GREEN ;
counter_reg <= 'b0;
end
endcase
*/
end
end
else if (i_enable) write_reg <= 1'b0;
end
always@* begin
if (line_reg < 239 ) begin
green_reg <= 4'b1111;
end
else begin
green_reg <= 4'b0000;
end
if (column_reg > 319 ) begin
red_reg <= 4'b1111;
end
else begin
red_reg <= 4'b0000;
end
end
assign o_addr = (line_reg[8:1] * COLUMNS/2) + column_reg [9:1] ;
assign o_data = {green_reg, red_reg , blue_reg};
//assign o_write = sw ? write_reg : 1'b0 ; // remowing switch
assign o_write = write_reg;
endmodule
+71
View File
@@ -0,0 +1,71 @@
// 100MHz clock on Basys3 -> 10ns period
// 50% duty cycle 5ns HIGH and 5ns LOW
//`timescale [time unit] / [time precision]
`timescale 10 ns / 1ns
`include "pattern_gen.v"
`include "clock_enable_param.v"
module pattern_gen_tb#( parameter
ADDR_WIDTH = 17,
DATA_WIDTH = 8
) ();
// for clock_divider
reg clk = 1'b0;
wire enable;
wire [ADDR_WIDTH-1:0] addr ;
wire [DATA_WIDTH-1:0] data ;
// generate clk
always #0.5 clk <= ~clk;
initial
begin
#76_800;
#76_800;
#76_800;
#76_800;
#76_800;
#76_800;
#76_800;
#76_800;
#76_800;
#76_800;
$display(" ");
$display("Use this command to open timing diagram:");
$display("gtkwave -f wave.vcd");
$display("----------------------------------------------");
$finish();
end
initial
begin
$display(" ");
$display("----------------------------------------------");
$display(" Starting Testbench...");
$dumpfile("wave.vcd");
$dumpvars(0);
end
clock_enable_param #(
.WAIT(1),
.WIDTH(2)
) clock_enable1 (
.clk(clk),
.enable(enable));
address_gen #(
.ADDR_WIDTH(ADDR_WIDTH),
.DATA_WIDTH(DATA_WIDTH)
) test_unit (
.clk(clk),
.i_enable(enable),
.o_addr(addr),
.o_data(data));
endmodule
+154
View File
@@ -0,0 +1,154 @@
// Default parameters for image transform module
// Four MSB are actual registers
// next two bits are one of modes selected by swishes. 4 modes are avilable
// LSB are camera bit. avilable two cameras. Camera 0 and camera 1.
//
//
module reg_reader #(parameter
CAM_LINE = 9,
CAM_PIXEL = 10//,
)(
input clk,
input i_enable,
input [24:0] i_data,
output [6:0] o_addr_rd,
// camera modes from input swiches
input [1:0] i_cam0_mode,
input [1:0] i_cam1_mode,
// 1st camera
output [CAM_PIXEL-1:0] o_cam0_WIDTH,
output [CAM_LINE-1:0] o_cam0_DEPTH,
output [24:0] o_cam0_T11,
output [24:0] o_cam0_T12,
output [24:0] o_cam0_T13,
output [24:0] o_cam0_T21,
output [24:0] o_cam0_T22,
output [24:0] o_cam0_T23,
output [24:0] o_cam0_T31,
output [24:0] o_cam0_T32,
output [24:0] o_cam0_T33,
// 2nd camera
output [CAM_PIXEL-1:0] o_cam1_WIDTH,
output [CAM_LINE-1:0] o_cam1_DEPTH,
output [24:0] o_cam1_T11,
output [24:0] o_cam1_T12,
output [24:0] o_cam1_T13,
output [24:0] o_cam1_T21,
output [24:0] o_cam1_T22,
output [24:0] o_cam1_T23,
output [24:0] o_cam1_T31,
output [24:0] o_cam1_T32,
output [24:0] o_cam1_T33
);
// Internal variables and registers
reg [6:0] r_count = 'b0;
reg [24:0] r_data = 'b0;
reg [CAM_PIXEL-1:0] r_cam0_WIDTH = 'b0;// 'd320;
reg [CAM_LINE-1:0] r_cam0_DEPTH = 'b0;// 'd240;
reg [24:0] r_cam0_T11 = 'b0;// 25'b0_000000000000_100000000000;
reg [24:0] r_cam0_T12 = 'b0;// 25'b0_000000000000_000000000000;
reg [24:0] r_cam0_T13 = 'b0;// 25'b0_000000000000_000000000000;
reg [24:0] r_cam0_T21 = 'b0;// 25'b0_000000000000_000000000000;
reg [24:0] r_cam0_T22 = 'b0;// 25'b0_000000000000_100000000000;
reg [24:0] r_cam0_T23 = 'b0;// 25'b0_000000000000_000000000000;
reg [24:0] r_cam0_T31 = 'b0;// 25'b0_000000000000_000000000000;
reg [24:0] r_cam0_T32 = 'b0;// 25'b0_000000000000_000000000000;
reg [24:0] r_cam0_T33 = 'b0;// 25'b0_000000000001_000000000000;
reg [CAM_PIXEL-1:0] r_cam1_WIDTH = 'b0;// 'd320;
reg [CAM_LINE-1:0] r_cam1_DEPTH = 'b0;// 'd240;
reg [24:0] r_cam1_T11 = 'b0;// 25'b0_000000000000_100000000000;
reg [24:0] r_cam1_T12 = 'b0;// 25'b0_000000000000_000000000000;
reg [24:0] r_cam1_T13 = 'b0;// 25'b0_000000000000_000000000000;
reg [24:0] r_cam1_T21 = 'b0;// 25'b0_000000000000_000000000000;
reg [24:0] r_cam1_T22 = 'b0;// 25'b0_000000000000_100000000000;
reg [24:0] r_cam1_T23 = 'b0;// 25'b0_000000000000_000000000000;
reg [24:0] r_cam1_T31 = 'b0;// 25'b0_000000000000_000000000000;
reg [24:0] r_cam1_T32 = 'b0;// 25'b0_000000000000_000000000000;
reg [24:0] r_cam1_T33 = 'b0;// 25'b0_000000000001_000000000000;
//--------------------------- synchonus logic------------------
always @ (posedge clk) begin
if(i_enable)begin
r_count <= r_count + 1;
end
if(i_enable) begin
case (r_count[0])
'b0 : begin
case (r_count[6:3])
'd0 : r_cam0_WIDTH <= i_data[CAM_PIXEL-1:0];
'd1 : r_cam0_DEPTH <= i_data[CAM_LINE-1:0];
'd2 : r_cam0_T11 <= i_data;
'd3 : r_cam0_T12 <= i_data;
'd4 : r_cam0_T13 <= i_data;
'd5 : r_cam0_T21 <= i_data;
'd6 : r_cam0_T22 <= i_data;
'd7 : r_cam0_T23 <= i_data;
'd8 : r_cam0_T31 <= i_data;
'd9 : r_cam0_T32 <= i_data;
'd10 : r_cam0_T33 <= i_data;
default: ;
endcase
end
'b1 : begin
case (r_count[6:3])
'd0 : r_cam1_WIDTH <= i_data[CAM_PIXEL-1:0];
'd1 : r_cam1_DEPTH <= i_data[CAM_LINE-1:0];
'd2 : r_cam1_T11 <= i_data;
'd3 : r_cam1_T12 <= i_data;
'd4 : r_cam1_T13 <= i_data;
'd5 : r_cam1_T21 <= i_data;
'd6 : r_cam1_T22 <= i_data;
'd7 : r_cam1_T23 <= i_data;
'd8 : r_cam1_T31 <= i_data;
'd9 : r_cam1_T32 <= i_data;
'd10 : r_cam1_T33 <= i_data;
default: ;
endcase
end
endcase
end
end
//------------------ combinational logic ----------------------
assign o_addr_rd = {r_count[6:3], (r_count[0])? i_cam1_mode : i_cam0_mode , r_count[0] };
// 1st camera
assign o_cam0_WIDTH = r_cam0_WIDTH;
assign o_cam0_DEPTH = r_cam0_DEPTH;
assign o_cam0_T11 = r_cam0_T11;
assign o_cam0_T12 = r_cam0_T12;
assign o_cam0_T13 = r_cam0_T13;
assign o_cam0_T21 = r_cam0_T21;
assign o_cam0_T22 = r_cam0_T22;
assign o_cam0_T23 = r_cam0_T23;
assign o_cam0_T31 = r_cam0_T31;
assign o_cam0_T32 = r_cam0_T32;
assign o_cam0_T33 = r_cam0_T33;
// 2nd camera
assign o_cam1_WIDTH = r_cam1_WIDTH;
assign o_cam1_DEPTH = r_cam1_DEPTH;
assign o_cam1_T11 = r_cam1_T11;
assign o_cam1_T12 = r_cam1_T12;
assign o_cam1_T13 = r_cam1_T13;
assign o_cam1_T21 = r_cam1_T21;
assign o_cam1_T22 = r_cam1_T22;
assign o_cam1_T23 = r_cam1_T23;
assign o_cam1_T31 = r_cam1_T31;
assign o_cam1_T32 = r_cam1_T32;
assign o_cam1_T33 = r_cam1_T33;
endmodule
+125
View File
@@ -0,0 +1,125 @@
// This file is Test Bench for top_vga_mem module
//
//
// 100MHz clock input from top module
// 50% duty cycle 5ns HIGH and 5ns LOW
//`timescale [time unit] / [time precision]
`timescale 10 ns / 1ns
//sub modules
`include "clock_enable_param.v"
//test modulea
`include "default_reg_writer.v"
`include "blockram.v"
`include "reg_reader.v"
module register_rd_wr_tb #(parameter
CAM_LINE = 9,
CAM_PIXEL = 10,
DEPTH = 88,
ADDR_WIDTH = 7,
DATA_WIDTH = 25
)();
//--------Internal register-----------
reg clk = 1'b0;
wire w_enable;
reg reset = 0;
wire [24:0] w_data_reg;
wire [6:0] w_addr_rd_reg;
wire w_config_default ;
wire [6:0] w_addr_default ;
wire [24:0] w_data_default ;
wire w_we_default ;
//---------Test script----------------
// 50% duty cycle clock
always #0.5 clk <= ~clk;
//-----Unit Under test---------------
default_reg_writer #(
.CAM_LINE(CAM_LINE),
.CAM_PIXEL(CAM_PIXEL)
) default_reg_writer1(
.clk(clk),
.i_enable(w_enable),
.i_reset(reset),
.o_configured(w_config_default),
.o_addr(w_addr_default),
.o_data(w_data_default) ,
.o_we(w_we_default)
);
reg_reader #(
.CAM_LINE(CAM_LINE),
.CAM_PIXEL(CAM_PIXEL)
) reg_reader1 (
.clk(clk),
.i_enable(w_enable),
.i_cam0_mode(2'b00),
.i_cam1_mode(2'b00),
.i_data(w_data_reg),
.o_addr_rd(w_addr_rd_reg)
);
rams_tdp_rf_rf #(
.DEPTH(DEPTH),
.ADDR_WIDTH(ADDR_WIDTH),
.DATA_WIDTH(DATA_WIDTH)
)
bram_reg(
// -------------------------PORT A
.clka( clk),
.ena(1'b1),
.wea( ),
.addra(w_addr_rd_reg),
.dia( ),
.doa(w_data_reg),
//---------------------------PORT B
.clkb( clk),
.addrb( w_config_default ? w_addr_default : w_addr_default ),
.enb( w_enable),
.web( w_config_default ? w_we_default : w_we_default),
.dib( w_config_default ? w_data_default : w_data_default),
.dob() // not connected
);
//------sub modules-------------------
clock_enable_param #(
// .WAIT(WAIT),
// .WIDTH(WAIT_WIDTH)
) clock_enable1 (
.clk(clk),
.enable(w_enable)
);
initial
begin
#0_500;
$display("*");
reset = 1;
#0_020;
reset = 0;
#3_500;
$display(" ");
$display("Use this command to open timing diagram:");
$display("gtkwave -f wave.vcd");
$display("----------------------------------------------");
$finish();
end
initial
begin
$display(" ");
$display("----------------------------------------------");
$display(" Starting Testbench...");
$dumpfile("wave.vcd");
$dumpvars(0);
end
endmodule
+72
View File
@@ -0,0 +1,72 @@
module rgb2gray #(
parameter r_koef = 17, // 0.3 in binary
g_koef = 37, // 0.59 in binary
b_koef = 7 , // 0.11 in binary
CAM_DATA_WIDTH = 12,
CAM_LINE = 9,
CAM_PIXEL = 10
) (
input clk,
input gray, // outputs gray if HIGH
// input form camera
input i_we,
input [CAM_DATA_WIDTH-1:0] i_data_wr,
input [CAM_LINE-1:0] i_line,
input [CAM_PIXEL-1:0] i_pixel,
// output
output o_we,
output [CAM_DATA_WIDTH-1:0] o_data_wr,
output [CAM_LINE-1:0] o_line,
output [CAM_PIXEL-1:0] o_pixel
);
//------------Internal variables and constants-----------
reg r_we1 = 0;
reg r_we2 = 0;
reg r_we3 = 0;
reg [CAM_LINE-1:0] r_line1;
reg [CAM_LINE-1:0] r_line2;
reg [CAM_LINE-1:0] r_line3;
reg [CAM_PIXEL-1:0] r_pixel1;
reg [CAM_PIXEL-1:0] r_pixel2;
reg [CAM_PIXEL-1:0] r_pixel3;
reg [10:0] r_red1 = 0;
reg [10:0] r_green1 = 0;
reg [10:0] r_blue1 = 0;
reg [10:0] r_data2 = 0;
reg [10:0] r_data3 = 0;
always@(posedge clk) begin
// 3rd cycle
r_we3 <= r_we2;
r_pixel3 <= r_pixel2;
r_line3 <= r_line2;
r_data3 <= r_data2;
// second cycle
r_we2 <= r_we1;
r_pixel2 <= r_pixel1;
r_line2 <= r_line1;
r_data2 <= r_red1 + r_green1 + r_blue1;
// first cycle
r_we1 <= i_we;
r_pixel1 <= i_pixel;
r_line1 <= i_line;
r_red1 <= i_data_wr[11:8] * r_koef;
r_green1 <= i_data_wr[7:4] * g_koef;
r_blue1 <= i_data_wr[3:0] * r_koef;
end
assign o_we = ~gray ? i_we : r_we3;
assign o_line = ~gray ? i_line : r_line3;
assign o_pixel = ~gray ? i_pixel : r_pixel3;
assign o_data_wr = ~gray ? i_data_wr :
r_data3[10] ?
12'hfff : {r_data3[9:6],r_data3[9:6],r_data3[9:6]}; // if overflow send all 1
endmodule
+414
View File
@@ -0,0 +1,414 @@
// TOP module
//
//
// `include "clock_divider_param.v"
// `include "clock_enable_param.v"
// `include "blockram2.v"
// `include "pattern_gen.v"
// `include "vga_module.v"
// `include "horizontal_counter.v"
// `include "vertical_counter.v"
// `include "UART_Loopback_module.v"
// `include "UART_TX.v"
// `include "UART_RX.v"
// `include "7segment_v2.v"
// `include "com_to_mem_FSM_hex.v"
// `include "com_to_mem_module.v"
// `include "ov7670_top.v"
// `include "debounce_switch.v"
// `include "ov7670_capture.v"
// `include "ov7670_controller.v"
// `include "imag_procesor.v"
// `include "default_reg_writer.v"
// `include "i2c_senderv2.v"
// `include "ov7670_registers.v"
// `include "imag_save.v"
// `include "rgb2gray.v"
// `include "rgb2gray2.v"
// `include "imag_transform.v"
// `include "reg_reader.v"
// `include "address_gen.v"
// `include "overlay.v"
// `include "two_cam_one_screen2.v"
// `include "lookuptable.v"
module top #( parameter
//pattern generator paremater
SPEED = 300,
//enable signal parameters
WAIT = 1,
WAIT_WIDTH = 2,
//memory parameters
ADDR_WIDTH = 17, // 19, //
DATA_WIDTH = 12,
DEPTH = 76_800, // 307_200,//
//VGA parameters
HSYNC_CLKS = 800,
HSYNC_DISPLAY = 640,
HSYNC_PULSE = 96,
HSYNC_FRONT_PORCH = 16,
HSYNC_BACK_PORCH = 48,
VSYNC_LINES = 521,
VSYNC_DISPLAY = 480,
VSYNC_PULSE = 2,
VSYNC_FRONT_PORCH = 10,
VSYNC_BACK_PORCH = 29,
// CAM buss
CAM_DATA_WIDTH = 12,
CAM_LINE = 9,
CAM_PIXEL = 10
)(
input clk,
output [11:0] led,
output [1:0] ledc, // led camera configuration indicator
//VGA inputs outputs
output [3:0] vgaRed,
output [3:0] vgaBlue,
output [3:0] vgaGreen,
output Hsync,
output Vsync,
input [2:0] sw,
input [8:0] im_p,
//UART
input RsRx, // UART RX Data
output RsTx, // UART TX Data
// 7 segment
output [6:0] seg,
output [3:0] an,
// camera inputs outputs
input ov7670_cam1_pclk,
output ov7670_cam1_mclk,
input ov7670_cam1_vs,
input ov7670_cam1_hs,
input [7:0] ov7670_cam1_data,
output ov7670_cam1_scl,
inout ov7670_cam1_sda,
output ov7670_cam1_pwdn,
output ov7670_cam1_reset,
input ov7670_cam2_pclk,
output ov7670_cam2_mclk,
input ov7670_cam2_vs,
input ov7670_cam2_hs,
input [7:0] ov7670_cam2_data,
output ov7670_cam2_scl,
inout ov7670_cam2_sda,
output ov7670_cam2_pwdn,
output ov7670_cam2_reset,
input btnC, // reconfigure camera
input btnU // reset button for registers blobk RAM
);
//------internal wires and registers--------
wire w_enable;
wire pixel_clk;
wire clk50;
wire w_write;
wire [ADDR_WIDTH-1:0] w_addr_wr;
wire [DATA_WIDTH-1:0] w_data_wr;
wire [ADDR_WIDTH-1:0] w_com_addr_wr;
wire [DATA_WIDTH-1:0] w_com_data_wr;
wire w_com_write;
wire [ADDR_WIDTH-1:0] w_com_addr_rd;
// wire [ADDR_WIDTH-1:0] w_addrb;
wire [ADDR_WIDTH-1:0] w_addr_rd;
wire [DATA_WIDTH-1:0] w_data_rd;
wire [DATA_WIDTH-1:0] w_camera_cam1_data_wr;
wire w_camera_cam1_we;
wire [CAM_LINE-1:0] w_line_cam1;
wire [CAM_PIXEL-1:0] w_pixel_cam1;
wire [DATA_WIDTH-1:0] w_camera_cam2_data_wr;
wire w_camera_cam2_we;
wire [CAM_LINE-1:0] w_line_cam2;
wire [CAM_PIXEL-1:0] w_pixel_cam2;
wire [ADDR_WIDTH-1:0] w_proces_addr_wr;
wire [DATA_WIDTH-1:0] w_proces_data_wr;
wire w_proces_we;
wire [DATA_WIDTH-1:0] w_doa_bram;
wire w_wea_bram;
wire [ADDR_WIDTH-1:0] w_addra_bram;
wire [DATA_WIDTH-1:0] w_dia_bram;
reg [DATA_WIDTH-1:0] r_led = 0;
wire w_config_default ;
wire [6:0] w_addr_default ;
wire [24:0] w_data_default ;
wire w_we_default ;
wire w_reset_default;
wire [DATA_WIDTH-1:0] w_doa_bram_old;
wire [24:0] w_data_reg;
wire [6:0] w_addr_rd_reg;
wire [6:0] w_addr_com_wr_reg ;
wire [24:0] w_data_com_reg ;
wire w_we_com_reg ;
//-----sub modules--------------------------
clock_enable_param #(
.WAIT(WAIT),
.WIDTH(WAIT_WIDTH)
) clock_enable1 (
.clk(clk),
.enable(w_enable)
);
clock_divider #(
.DIVIDER(2),
.WIDTH(3)
) clk25mhz_gen (
.clk(clk),
.clk_out(pixel_clk)
);
clock_divider #(
.DIVIDER(1),
.WIDTH(3)
) clk50mhz_gen (
.clk(clk),
.clk_out(clk50)
);
pattern_gen #(
.DEPTH(DEPTH),
.ADDR_WIDTH(ADDR_WIDTH),
.DATA_WIDTH(DATA_WIDTH),
.SPEED(SPEED)
) pattern_gen1 (
.clk(clk),
// .sw(sw[1]),
.i_enable(w_enable),
.o_addr(w_addr_wr),
.o_data(w_data_wr),
.o_write(w_write)
);
rams_tdp_rf_rf #(
.DEPTH(DEPTH),
.ADDR_WIDTH(ADDR_WIDTH),
.DATA_WIDTH(DATA_WIDTH))
bram3(
// -------------------------PORT A
.clka(clk),
.ena( 1'b1 /*w_enable*/),
.wea( w_wea_bram ),
.addra( w_addra_bram ),
.dia( w_dia_bram ),
.doa( w_doa_bram ),
//---------------------------PORT B
.clkb(clk),
.addrb( w_addr_rd ),
.enb(w_enable),
//.web(),
//.dib(),
.dob(w_data_rd));
vga_module #(
.ADDR_WIDTH(ADDR_WIDTH),
.DATA_WIDTH(DATA_WIDTH),
.DEPTH(DEPTH),
.HSYNC_CLKS(HSYNC_CLKS),
.HSYNC_DISPLAY(HSYNC_DISPLAY),
.HSYNC_PULSE(HSYNC_PULSE),
.HSYNC_FRONT_PORCH(HSYNC_FRONT_PORCH),
.HSYNC_BACK_PORCH(HSYNC_BACK_PORCH),
.VSYNC_LINES(VSYNC_LINES) ,
.VSYNC_DISPLAY(VSYNC_DISPLAY) ,
.VSYNC_PULSE(VSYNC_PULSE) ,
.VSYNC_FRONT_PORCH(VSYNC_FRONT_PORCH) ,
.VSYNC_BACK_PORCH(VSYNC_BACK_PORCH)
) vga_module1 (
.clk(pixel_clk),
.o_vgaRed(vgaRed),
.o_vgaBlue(vgaBlue),
.o_vgaGreen(vgaGreen),
.o_Hsync(Hsync),
.o_Vsync(Vsync),
.o_display(),
.o_addr_rd(w_addr_rd),
.o_data_rd(w_data_rd)
);
com_to_mem #(
.WAIT(WAIT),
.WAIT_WIDTH(WAIT_WIDTH),
.ADDR_WIDTH(ADDR_WIDTH),
.DATA_WIDTH(DATA_WIDTH),
.DEPTH(DEPTH)
) com_to_mem1 (
.clk(clk),
.sw(sw[0]),
//.i_data_rd(w_doa_bram),
.i_enable(w_enable),
.o_addr_wr(w_com_addr_wr),
.o_addr_rd(w_com_addr_rd),
.o_data_wr(w_com_data_wr),
.o_write(w_com_write),
.RsRx(RsRx), // UART RX Data
.RsTx(RsTx), // UART TX Data
.seg(seg),
.an(an),
.o_addr_wr_reg(w_addr_com_wr_reg),
.o_data_reg(w_data_com_reg),
.o_we_reg(w_we_com_reg)
);
ov7670_top #(
.CAM_DATA_WIDTH(CAM_DATA_WIDTH),
.CAM_LINE(CAM_LINE),
.CAM_PIXEL(CAM_PIXEL)
) ov7670_cam1(
.clk(pixel_clk),
.btn(btnC),
.config_finished(ledc[0]), // configuration finished
.o_data_wr(w_camera_cam1_data_wr),
.o_line(w_line_cam1),
.o_pixel(w_pixel_cam1),
.we(w_camera_cam1_we),
.ov7670_pclk(ov7670_cam1_pclk),
.ov7670_mclk(ov7670_cam1_mclk),
.ov7670_vs(ov7670_cam1_vs),
.ov7670_hs(ov7670_cam1_hs),
.ov7670_data(ov7670_cam1_data),
.ov7670_scl(ov7670_cam1_scl),
.ov7670_sda(ov7670_cam1_sda),
.ov7670_pwdn(ov7670_cam1_pwdn),
.ov7670_reset(ov7670_cam1_reset)
);
ov7670_top #(
.CAM_DATA_WIDTH(CAM_DATA_WIDTH),
.CAM_LINE(CAM_LINE),
.CAM_PIXEL(CAM_PIXEL)
) ov7670_cam2(
.clk(pixel_clk),
.btn(btnC),
.config_finished(ledc[1]),
.o_data_wr(w_camera_cam2_data_wr),
.o_line(w_line_cam2),
.o_pixel(w_pixel_cam2),
.we(w_camera_cam2_we),
.ov7670_pclk(ov7670_cam2_pclk),
.ov7670_mclk(ov7670_cam2_mclk),
.ov7670_vs(ov7670_cam2_vs),
.ov7670_hs(ov7670_cam2_hs),
.ov7670_data(ov7670_cam2_data),
.ov7670_scl(ov7670_cam2_scl),
.ov7670_sda(ov7670_cam2_sda),
.ov7670_pwdn(ov7670_cam2_pwdn),
.ov7670_reset(ov7670_cam2_reset)
);
imag_procesor #(
.CAM_DATA_WIDTH(CAM_DATA_WIDTH),
.CAM_LINE(CAM_LINE),
.CAM_PIXEL(CAM_PIXEL)
) imag_procesor(
.im_p(im_p),
.clk(clk),
.clk25(pixel_clk),
.clk50(clk50),
.i_enable(w_enable),
.i_data_reg(w_data_reg),
.o_addr_rd_reg(w_addr_rd_reg),
.i_we_cam2(w_camera_cam2_we),
.i_data_cam2_wr(w_camera_cam2_data_wr),
.i_line_cam2(w_line_cam2),
.i_pixel_cam2(w_pixel_cam2),
.i_we_cam1(w_camera_cam1_we),
.i_data_cam1_wr(w_camera_cam1_data_wr),
.i_line_cam1(w_line_cam1),
.i_pixel_cam1(w_pixel_cam1),
.o_we(w_proces_we),
.o_addr_wr(w_proces_addr_wr),
.o_data_wr(w_proces_data_wr)
);
rams_tdp_rf_rf #(
.DEPTH(88),
.ADDR_WIDTH(7),
.DATA_WIDTH(25))
bram_reg(
// -------------------------PORT A
.clka( clk),
.ena( 1'b1 /*w_enable*/ ),
.wea( ),
.addra(w_addr_rd_reg),
.dia( ),
.doa(w_data_reg),
//---------------------------PORT B
.clkb( clk),
.addrb( w_config_default ? w_addr_com_wr_reg : w_addr_default ),
.enb( w_enable),
.web( w_config_default ? w_we_com_reg : w_we_default),
.dib( w_config_default ? w_data_com_reg : w_data_default),
.dob() // not connected
);
default_reg_writer default_reg_writer1(
.clk(clk),
.i_enable(w_enable),
.i_reset(w_reset_default),
.o_configured(w_config_default),
.o_addr(w_addr_default),
.o_data(w_data_default) ,
.o_we(w_we_default)
);
debounce_switch debounce_switch_reset(
.clk(clk),
.i_switch(btnU),
.o_switch(w_reset_default)
);
always@(posedge clk) begin
if (~w_wea_bram) begin
r_led <= w_doa_bram;
// r_doa_bram_old <= w_doa_bram;
end
else begin
r_led <= w_doa_bram_old;
end
end
assign led[11:0] = r_led ;
assign w_doa_bram_old = r_led;
assign w_addra_bram = ~w_wea_bram ? w_com_addr_rd : // if we LOW port A address connected to com_to_mem module
(sw[2:1] == 2'b00) ? w_com_addr_wr :
(sw[2:1] == 2'b01) ? w_addr_wr :
(sw[2:1] == 2'b10) ? w_proces_addr_wr :
w_proces_addr_wr ; // sw[2:1] == 2'b11
assign w_wea_bram = (sw[2:1] == 2'b00) ? w_com_write :
(sw[2:1] == 2'b01) ? w_write :
(sw[2:1] == 2'b10) ? w_proces_we :
w_proces_we ; // sw[2:1] == 2'b11
assign w_dia_bram = (sw[2:1] == 2'b00) ? w_com_data_wr :
(sw[2:1] == 2'b01) ? w_data_wr :
(sw[2:1] == 2'b10) ? w_proces_data_wr :
w_proces_data_wr ;
endmodule
+593
View File
@@ -0,0 +1,593 @@
// This file is Test Bench for top_vga_mem module
//
//
// 100MHz clock on Basys3 -> 10ns period
// 50% duty cycle 5ns HIGH and 5ns LOW
//`timescale [time unit] / [time precision]
`timescale 10 ns / 1ns
//sub modules
`include "clock_divider_param.v"
`include "clock_enable_param.v"
`include "blockram.v"
`include "pattern_gen.v"
`include "vga_module.v"
`include "horizontal_counter.v"
`include "vertical_counter.v"
`include "UART_Loopback_module.v"
`include "UART_TX.v"
`include "UART_RX.v"
`include "7segment.v"
`include "com_to_mem_FSM_hex.v"
`include "com_to_mem_module.v"
`include "ov7670_top.v"
`include "debounce_switch.v"
`include "ov7670_capture.v"
`include "ov7670_controller.v"
`include "imag_procesor.v"
`include "default_reg_writer.v"
`include "i2c_sender.v"
`include "ov7670_registers.v"
`include "imag_save.v"
`include "rgb2gray.v"
`include "imag_transform.v"
`include "reg_reader.v"
`include "address_gen.v"
`include "overlay.v"
`include "two_cam_one_screen.v"
`include "lookuptable.v"
//top module
`include "top.v"
module top_vga_mem_tb#( parameter
WAIT = 1,
WAIT_WIDTH = 2,
SPEED = 2,
//memory parameters
ADDR_WIDTH = 17, //19, //
DATA_WIDTH = 12,
DEPTH = 307_200//76_800, //
)();
reg clk = 1'b0;
reg pclk = 1'b0;
reg hs = 1'b0;
reg vs = 1'b0;
// 50% duty cycle clock
always #0.5 clk <= ~clk;
always #2 pclk <= ~pclk;
always #100 hs <= 1;
always #102 hs <= 0;
always #200 vs <= 1;
always #202 vs <= 0;
reg RsRx;
wire RsTx;
top_vga_mem #(
.SPEED(SPEED),
.ADDR_WIDTH(ADDR_WIDTH),
.DATA_WIDTH(DATA_WIDTH),
.DEPTH(DEPTH)
)Test_Unit(
.clk(clk),
.RsRx(RsRx),
.RsTx(RsTx),
.sw(3'b101),
.ov7670_cam1_pclk(pclk),
.ov7670_cam2_pclk(pclk),
.ov7670_cam1_vs(vs),
.ov7670_cam1_hs(hs),
.ov7670_cam2_vs(vs),
.ov7670_cam2_hs(hs),
.im_p(9'b00_01_01_000)
);
initial begin
// starting UART transition
// h70 -> P
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h32 -> 2
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h63 -> c
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
// h38 -> 8
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#10_000;
// h72 -> r
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h35 -> 5
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h35 -> 5
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#10_000;
// h70 -> p
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h35 -> 5
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h35 -> 5
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h32 -> 2
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h35 -> 5
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h35 -> 5
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#10_000;
// h72 -> r
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h30 -> 0
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h35 -> 5
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
// h35 -> 5
#9000;
#0 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 1;
#868 RsRx = 1;
#868 RsRx = 0;
#868 RsRx = 0;
#868 RsRx = 1;
#10_000;
end
initial begin
#000_001;
$display("*");
#030_000;
$display("*");
#030_000;
$display("*");
#030_000;
$display("*");
#030_000;
$display("*");
#030_000;
$display("*");
#030_000;
$display("*");
#030_000;
$display("*");
#030_000;
$display("*");
#030_000;
$display("*");
#030_000;
$display("*");
#030_000;
$display("*");
#030_000;
$display("*");
#030_000;
$display("*");
#030_000;
$display("*");
#030_000;
$display("*");
#030_000;
$display("*");
#030_000;
$display("*");
#030_000;
$display("*");
#030_000;
$display("*");
$display(" ");
$display("Use this command to open timing diagram:");
$display("gtkwave -f wave.vcd");
$display("----------------------------------------------");
$finish();
end
initial
begin
$display(" ");
$display("----------------------------------------------");
$display(" Starting Testbench...");
$dumpfile("wave.vcd");
$dumpvars(0);
end
endmodule
+254
View File
@@ -0,0 +1,254 @@
module two_cam_one_screen#(
parameter CAM_DATA_WIDTH = 12,
CAM_LINE = 9,
CAM_PIXEL = 10
) (
input clk1,
input clk2,
input clk,
input [1:0] im_p, // image processor controls
// input form camera
//cam1
input i_we_cam0,
input [CAM_DATA_WIDTH-1:0] i_data_cam0,
input [CAM_LINE-1:0] i_line_cam0,
input [CAM_PIXEL-1:0] i_pixel_cam0,
input [CAM_LINE-1:0] i_imag_depth_cam0,
input [CAM_PIXEL-1:0] i_imag_width_cam0,
//input i_imag_resized_cam0,
//cam2
input i_we_cam1,
input [CAM_DATA_WIDTH-1:0] i_data_cam1,
input [CAM_LINE-1:0] i_line_cam1,
input [CAM_PIXEL-1:0] i_pixel_cam1,
input [CAM_LINE-1:0] i_imag_depth_cam1,
input [CAM_PIXEL-1:0] i_imag_width_cam1,
//input i_imag_resized_cam1,
// output
output [CAM_LINE-1:0] o_line,
output [CAM_PIXEL-1:0] o_pixel,
output o_we,
output [CAM_DATA_WIDTH-1:0] o_data_wr,
output [CAM_LINE-1:0] o_imag_depth,
output [CAM_PIXEL-1:0] o_imag_width
);
//------------Internal variables and constants-----------
// reg [CAM_LINE-1:0] r_offset_y;
// reg [CAM_PIXEL-1:0] r_offset_x;
// reg [CAM_LINE:0] r_imag_depth_summ;
// reg [CAM_PIXEL:0] r_imag_width_summ;
// reg [CAM_PIXEL-1:0]
// r_imag_width1 = 0,
// r_imag_width2 = 0,
// r_imag_width3 = 0;
// reg [CAM_LINE-1:0]
// r_imag_depth1 = 0,
// r_imag_depth2 = 0,
// r_imag_depth3 = 0;
// reg [CAM_LINE-1:0]
// r_imag_depth1_cam0,
// r_imag_depth2_cam0,
// r_imag_depth1_cam1,
// r_imag_depth2_cam1 ;
// reg [CAM_PIXEL-1:0]
// r_imag_width1_cam0,
// r_imag_width2_cam0,
// r_imag_width1_cam1,
// r_imag_width2_cam1 ;
reg [CAM_PIXEL-1:0]
r_pixel1_cam1 = 0,
r_pixel2_cam1 = 0,
r_pixel3_cam1 = 0,
r_pixel4_cam1 = 0;
reg [CAM_PIXEL-1:0]
r_pixel1_cam0 = 0,
r_pixel2_cam0 = 0,
r_pixel3_cam0 = 0,
r_pixel4_cam0 = 0;
reg [CAM_LINE-1:0]
r_line1_cam1 = 0,
r_line2_cam1 = 0,
r_line3_cam1 = 0,
r_line4_cam1 = 0;
reg [CAM_LINE-1:0]
r_line1_cam0 = 0,
r_line2_cam0 = 0,
r_line3_cam0 = 0,
r_line4_cam0 = 0;
reg [CAM_DATA_WIDTH-1:0]
r_data1_cam0 = 0,
r_data2_cam0 = 0,
r_data3_cam0 = 0,
r_data4_cam0 = 0;
reg [CAM_DATA_WIDTH-1:0]
r_data1_cam1 = 0,
r_data2_cam1 = 0,
r_data3_cam1 = 0,
r_data4_cam1 = 0;
reg
r_we1_cam0 = 0,
r_we2_cam0 = 0,
r_we3_cam0 = 0,
r_we4_cam0 = 0;
reg
r_we1_cam1 = 0,
r_we2_cam1 = 0,
r_we3_cam1 = 0,
r_we4_cam1 = 0;
reg [0:0]
cam_select = 0;
reg
r_we_out = 0;
reg [CAM_DATA_WIDTH-1:0]
r_data_out = 0;
reg [CAM_LINE-1:0]
r_line_out = 0;
reg [CAM_PIXEL-1:0]
r_pixel_out = 0;
//------------Syncronus logic---------------------------
always@(negedge clk1)begin
// -------------------1st cycle
//if(clk50==1)begin
if (i_pixel_cam0 < 'd159 ) begin
r_pixel1_cam0 <= i_pixel_cam0;
end else begin
r_pixel1_cam0 <= 'd159;
end
if (i_pixel_cam1 < 'd159 ) begin
r_pixel1_cam1 <= i_pixel_cam1;
end else begin
r_pixel1_cam1 <= 'd159;
end
r_data1_cam0 <= i_data_cam0;
r_we1_cam0 <= i_we_cam0;
r_line1_cam0 <= i_line_cam0;
r_data1_cam1 <= i_data_cam1;
r_we1_cam1 <= i_we_cam1;
r_line1_cam1 <= i_line_cam1;
//end
end
always@(negedge clk2)begin
//if(clk50==0)begin
// -------------------2nd cycle
r_data2_cam0 <= r_data1_cam0;
r_data2_cam1 <= r_data1_cam1;
r_we2_cam0 <= r_we1_cam0;
r_we2_cam1 <= r_we1_cam1;
r_pixel2_cam1 <= r_pixel1_cam1;
r_pixel2_cam0 <= r_pixel1_cam0 + 'd160;
r_line2_cam0 <= r_line1_cam0;
r_line2_cam1 <= r_line1_cam1;
//end
end
always@(negedge clk1)begin
//if(clk50==1)begin
//------------------3rd cycle
/*
r_data_out <= r_data2_cam0;
r_we_out <= r_we2_cam0;
r_pixel_out <= r_pixel2_cam0;
r_line_out <= r_line2_cam0;
*/
r_data3_cam0 <= r_data2_cam0;
r_we3_cam0 <= r_we2_cam0;
r_pixel3_cam0 <= r_pixel2_cam0;
r_line3_cam0 <= r_line2_cam0;
r_data3_cam1 <= r_data2_cam1;
r_we3_cam1 <= r_we2_cam1;
r_pixel3_cam1 <= r_pixel2_cam1;
r_line3_cam1 <= r_line2_cam1;
//end
end
always@(negedge clk2)begin
//if(clk50==0)begin
//------------------4th cycle
/*
r_data_out <= r_data3_cam1;
r_we_out <= r_we3_cam1;
r_pixel_out <= r_pixel3_cam1;
r_line_out <= r_line3_cam1;
r_data4_cam0 <= r_data3_cam0;
r_line4_cam0 <= r_line3_cam0;
r_we4_cam0 <= r_we3_cam0;
r_pixel4_cam0 <= r_pixel3_cam0;
*/
r_we4_cam1 <= r_we3_cam1;
r_pixel4_cam1 <= r_pixel3_cam1;
r_data4_cam1 <= r_data3_cam1;
r_line4_cam1 <= r_line3_cam1;
//end
end
always@(negedge clk )begin
cam_select <= ~cam_select;
end
// assign o_line = r_line_out[CAM_LINE-1:0]; //~counter[0] ? r_line4_cam1 : r_line3_cam0;
// assign o_pixel = r_pixel_out[CAM_PIXEL-1:0]; //~counter[0] ? r_pixel4_cam1 : r_pixel3_cam0;
// assign o_we = r_we_out; // 1'b1; //~counter[0] ? r_we4_cam1 : r_we3_cam0;
// assign o_data_wr = r_data_out;// ~counter[0] ? r_data4_cam1 : r_data3_cam0;
// assign o_imag_depth = 240;//~counter[0] ? r_imag_depth3 : r_imag_depth2;
// assign o_imag_width = 320;//~counter[0] ? r_imag_width3 : r_imag_width2;
assign o_line = im_p[1]? cam_select ? r_line4_cam1 : r_line3_cam0
: im_p[0] ? i_line_cam0 : i_line_cam1 ;
assign o_pixel = im_p[1]? cam_select ? r_pixel4_cam1 : r_pixel3_cam0
: im_p[0] ? i_pixel_cam0 : i_pixel_cam1 ;
assign o_we = im_p[1]? cam_select ? r_we4_cam1 : r_we3_cam0
: im_p[0] ? i_we_cam0 : i_we_cam1 ;
assign o_data_wr = im_p[1]? cam_select ? r_data4_cam1 : r_data3_cam0
: im_p[0] ? i_data_cam0 : i_data_cam1 ;
// assign o_line = r_line3_cam0;
// assign o_pixel = r_pixel3_cam0;
// assign o_we = r_we3_cam0;
// assign o_data_wr = r_data3_cam0;
assign o_imag_depth = im_p[1]? 240
: im_p[0] ? i_imag_depth_cam0 : i_imag_depth_cam1 ;
assign o_imag_width = im_p[1]? 320
: im_p[0] ? i_imag_width_cam0 : i_imag_width_cam1 ;
endmodule
+73
View File
@@ -0,0 +1,73 @@
module vertical_counter #(
parameter
VSYNC_LINES = 521,
VSYNC_DISPLAY = 480,
VSYNC_PULSE = 2,
VSYNC_FRONT_PORCH = 10,
VSYNC_BACK_PORCH = 29
)(
//input clk,
input i_Hsync,
output o_Vsync,
output o_v_display,
output [8:0] o_v_line
);
//----------Internal registers, constants and wariables-----
reg vsync_reg = 1'b1;
reg [9:0] counter_reg = 'h0;
reg [8:0] counter_line_reg = 'h0;
reg [2:0] r_state=VS_FRONT_PORCH, r_next=VS_FRONT_PORCH;
localparam [2:0] VS_FRONT_PORCH = 'h0,
VS_PULSE = 'h1,
VS_BACK_PORCH = 'h2,
VS_DISPLAY = 'h3;
//---------state register sequential always block-----------
always @(posedge i_Hsync ) begin
r_state <= r_next;
end
//----next state & outputs, combinational always block------
always@(posedge i_Hsync) begin
counter_reg <= counter_reg + 1;
case (r_state)
VS_FRONT_PORCH: begin
vsync_reg <= 1'b1;
if(counter_reg == VSYNC_FRONT_PORCH - 2)
r_next <= VS_PULSE;
end
VS_PULSE:begin
vsync_reg <= 1'b0;
if(counter_reg == VSYNC_FRONT_PORCH +
VSYNC_PULSE - 2)
r_next <= VS_BACK_PORCH;
end
VS_BACK_PORCH:begin
vsync_reg <= 1'b1;
if(counter_reg == VSYNC_FRONT_PORCH +
VSYNC_PULSE +
VSYNC_BACK_PORCH - 2) begin
r_next <= VS_DISPLAY;
counter_line_reg <= 'h0;
end
end
VS_DISPLAY:begin
vsync_reg <= 1'b1;
counter_line_reg <= counter_line_reg + 1;
if(counter_reg == VSYNC_FRONT_PORCH +
VSYNC_PULSE +
VSYNC_BACK_PORCH +
VSYNC_DISPLAY - 1) begin
r_next <= VS_FRONT_PORCH;
counter_reg <= 'h0;
end
end
endcase
end
assign o_Vsync = vsync_reg;
assign o_v_display = (counter_line_reg >= 1 && counter_line_reg <= VSYNC_DISPLAY) ? 1'b1 : 1'b0 ;
assign o_v_line = counter_line_reg - 1 ;
endmodule
+76
View File
@@ -0,0 +1,76 @@
module vga_module#(
parameter
ADDR_WIDTH = 17,
DATA_WIDTH = 12,
DEPTH = 76_800, // 307_200,//
HSYNC_CLKS = 800,
HSYNC_DISPLAY = 640,
HSYNC_PULSE = 96,
HSYNC_FRONT_PORCH = 16,
HSYNC_BACK_PORCH = 48,
VSYNC_LINES = 521,
VSYNC_DISPLAY = 480,
VSYNC_PULSE = 2,
VSYNC_FRONT_PORCH = 10,
VSYNC_BACK_PORCH = 29
)(
input clk,
output [3:0] o_vgaRed,
output [3:0] o_vgaBlue,
output [3:0] o_vgaGreen,
output o_Hsync,
output o_Vsync,
output o_display,
output [ADDR_WIDTH-1:0] o_addr_rd,
input [DATA_WIDTH-1:0] o_data_rd
);
//-------Internal registers and wires--------------
wire w_v_display;
wire w_h_display;
wire [9:0] pixel;
wire [8:0] line;
//-------sub modules-------------------------------
horizontal_counter #(
.HSYNC_CLKS(HSYNC_CLKS) ,
.HSYNC_DISPLAY(HSYNC_DISPLAY) ,
.HSYNC_PULSE(HSYNC_PULSE) ,
.HSYNC_FRONT_PORCH(HSYNC_FRONT_PORCH) ,
.HSYNC_BACK_PORCH(HSYNC_BACK_PORCH)
) horizontal_counter1 (
.clk(clk),
.o_Hsync(o_Hsync),
.o_h_display(w_h_display),
.o_h_pixel(pixel)
);
vertical_counter #(
.VSYNC_LINES(VSYNC_LINES) ,
.VSYNC_DISPLAY(VSYNC_DISPLAY) ,
.VSYNC_PULSE(VSYNC_PULSE) ,
.VSYNC_FRONT_PORCH(VSYNC_FRONT_PORCH) ,
.VSYNC_BACK_PORCH(VSYNC_BACK_PORCH)
) vertical_counter1 (
//.clk(clk),
.i_Hsync(o_Hsync),
.o_Vsync(o_Vsync),
.o_v_display(w_v_display),
.o_v_line(line)
);
assign o_display = (w_v_display && w_h_display) ;
assign o_vgaRed = o_display ? o_data_rd[11:8] : 4'h0;
assign o_vgaBlue = o_display ? o_data_rd[3:0] : 4'h0;
assign o_vgaGreen = o_display ? o_data_rd[7:4] : 4'h0;
/*
assign o_addr_rd = (((line*HSYNC_DISPLAY) + pixel + 1) == HSYNC_DISPLAY * VSYNC_DISPLAY ) ?
'h0 : ((line[8:1]) * HSYNC_DISPLAY/2 ) + pixel[9:1] + 1 ; // get next pixel
*/
assign o_addr_rd =
((line[8:1]) * 'd320 ) + pixel[9:1];// + 1;
endmodule