- Coolrunner II X2C256 - 144pin CPLD, 3 x OV9121, 2 x Sram( 1M x 16bits) , Cypress USB Fifo
- Schematic
- State Diagram
- Timing Chart
- Verilog code
`define CONFIG_RISING_EDGE_CLK
//`define CONFIG_FALLING_EDGE_CLK
module triple_camera(RESET, TRIG, CLK, LED,
VSYNC, HREF_DN, HREF_MID, HREF_UP, D_DN, D_MID, D_UP,
nWE, nOE, A, IO,
nFLAG, nPKTEND, nSLWR, FD);
input wire RESET; // Reset CPLD
input wire TRIG; // Start Data Transfer
input wire CLK; // External Main Clock
output wire [3:0] LED; // Express the Status of CPLD Processing
input wire VSYNC; // Vertical Synchronization from Image Sensor
input wire HREF_DN; // Horizontal Reference from Image Sensor
input wire HREF_MID;
input wire HREF_UP;
input wire [7:0] D_UP; // Pixel Data from Up Image Sensor
input wire [7:0] D_MID; // Pixel Data from Mid Image Sensor
input wire [7:0] D_DN; // Pixel Data from Dn Image Sensor
output reg nWE; // Write Enable for Memory
output reg nOE; // Read Enable(Output Enable) for Memory
parameter ADDR_SIZE = 20;
output wire [ADDR_SIZE-1:0] A; // Address of Memory
inout wire [31:0] IO; // Data Bus of Memory
input wire nFLAG; // Programmable Flag informing 4 bytes before full of USB FIFO
output wire nPKTEND; // Flush internal FIFO of USB into Host
output reg nSLWR; // Transfer Data Enable to USB FIFO
output reg [15:0] FD; // Data Bus for USB FIFO
// camera FSM
parameter CAMERA_STATE_SIZE = 12;
parameter CAMERA_IDLE = 12'b000000000001;
parameter CAMERA_WAIT_VSYNC = 12'b000000000010;
parameter CAMERA_VSYNC = 12'b000000000100;
parameter CAMERA_WAIT_HREF = 12'b000000001000;
parameter CAMERA_H0 = 12'b000000010000;
parameter CAMERA_H1 = 12'b000000100000;
parameter CAMERA_H2 = 12'b000001000000;
parameter CAMERA_H3 = 12'b000010000000;
parameter CAMERA_H4 = 12'b000100000000;
parameter CAMERA_H5 = 12'b001000000000;
parameter CAMERA_H6 = 12'b010000000000;
parameter CAMERA_H7 = 12'b100000000000;
reg [CAMERA_STATE_SIZE-1:0] up_cam_state;
reg [CAMERA_STATE_SIZE-1:0] mid_cam_state;
reg [CAMERA_STATE_SIZE-1:0] dn_cam_state;
reg [7:0] write_data0_0;
reg [7:0] write_data0_1;
reg [7:0] write_data0_2;
reg [7:0] write_data0_3;
reg write_pend0;
reg [7:0] write_data1_0;
reg [7:0] write_data1_1;
reg [7:0] write_data1_2;
reg [7:0] write_data1_3;
reg write_pend1;
reg [7:0] write_data2_0;
reg [7:0] write_data2_1;
reg [7:0] write_data2_2;
reg [7:0] write_data2_3;
reg [ADDR_SIZE:0] write_addr;
/* always @(posedge nWE or posedge RESET) begin
if (RESET) write_addr <= 0;
else write_addr <= write_addr + 1;
end*/
wire nWERise;
reg nWEPre;
always @(posedge RESET or negedge CLK)
begin
if(RESET)
nWEPre <= 1'b1;
else
nWEPre <= nWE;
end
assign nWERise = nWE & ~nWEPre;
always @(posedge RESET or negedge CLK)
begin
if(RESET)
write_addr <= 0;
else if(nWERise)
write_addr <= write_addr + 1;
end
reg [ADDR_SIZE:0] read_addr;
/* always @(posedge nOE or posedge RESET) begin
if (RESET) read_addr <= 0;
else read_addr <= read_addr + 1;
end
*/
wire nOERise;
reg nOEPre;
always @(posedge RESET or negedge CLK)
begin
if(RESET)
nOEPre <= 1'b1;
else
nOEPre <= nOE;
end
assign nOERise = nOE & ~nOEPre;
always @(posedge RESET or negedge CLK)
begin
if(RESET)
read_addr <= 0;
else if(nOERise)
read_addr <= read_addr + 1;
end
/* reg empty;
always @(write_addr or read_addr) begin
if (~|(write_addr[ADDR_SIZE:0]^read_addr[ADDR_SIZE:0])) empty <= 1;
else empty <= 0;
end
*/
reg read_flag;
wire empty;
assign empty = ~|(write_addr[ADDR_SIZE:0] ^ read_addr[ADDR_SIZE:0]);
`ifdef CONFIG_RISING_EDGE_CLK
always @(posedge RESET or posedge CLK) begin
`else //CONFIG_FALLING_EDGE_CLK
always @(posedge RESET or negedge CLK) begin
`endif
if (RESET)
begin
up_cam_state <= CAMERA_IDLE;
write_pend0 <= 0;
write_pend1 <= 0;
nWE <= 1;
read_flag <= 0;
end
else
begin
write_pend0 <= 0;
write_pend1 <= 0;
nWE <= 1;
if (nFLAG & (~empty))
read_flag <= 1;
else
read_flag <= 0;
case (up_cam_state)
CAMERA_IDLE:
if (TRIG)
up_cam_state <= CAMERA_WAIT_VSYNC;
else
up_cam_state <= CAMERA_IDLE;
CAMERA_WAIT_VSYNC:
if (VSYNC)
up_cam_state <= CAMERA_VSYNC;
else
up_cam_state <= CAMERA_WAIT_VSYNC;
CAMERA_VSYNC:
if (VSYNC)
up_cam_state <= CAMERA_VSYNC;
else
up_cam_state <= CAMERA_WAIT_HREF;
CAMERA_WAIT_HREF:
if (HREF_UP)
begin
up_cam_state <= CAMERA_H0;
write_data0_2 <= D_UP;
end
else
begin
if (VSYNC)
up_cam_state <= CAMERA_IDLE;
else
up_cam_state <= CAMERA_WAIT_HREF;
end
CAMERA_H0:
up_cam_state <= CAMERA_H1;
CAMERA_H1:
begin
up_cam_state <= CAMERA_H2;
write_data1_1 <= D_UP;
read_flag <= 0;
end
CAMERA_H2:
begin
up_cam_state <= CAMERA_H3;
write_pend0 <= 1;
nWE <= 0;
end
CAMERA_H3:
begin
up_cam_state <= CAMERA_H4;
write_data2_0 <= D_UP;
read_flag <= 0;
end
CAMERA_H4:
begin
up_cam_state <= CAMERA_H5;
write_pend1 <= 1;
nWE <= 0;
end
CAMERA_H5:
begin
up_cam_state <= CAMERA_H6;
write_data2_3 <= D_UP;
read_flag <= 0;
end
CAMERA_H6:
begin
up_cam_state <= CAMERA_H7;
nWE <= 0;
end
CAMERA_H7:
if (HREF_UP)
begin
up_cam_state <= CAMERA_H0;
write_data0_2 <= D_UP;
end
else
begin
up_cam_state <= CAMERA_WAIT_HREF;
end
default:
up_cam_state <= CAMERA_IDLE;
endcase
end
end
`ifdef CONFIG_RISING_EDGE_CLK
always @(posedge RESET or posedge CLK) begin
`else //CONFIG_FALLING_EDGE_CLK
always @(posedge RESET or negedge CLK) begin
`endif
if (RESET)
begin
mid_cam_state <= CAMERA_IDLE;
end
else
begin
case (mid_cam_state)
CAMERA_IDLE:
if (TRIG)
mid_cam_state <= CAMERA_WAIT_VSYNC;
else
mid_cam_state <= CAMERA_IDLE;
CAMERA_WAIT_VSYNC:
if (VSYNC)
mid_cam_state <= CAMERA_VSYNC;
else
mid_cam_state <= CAMERA_WAIT_VSYNC;
CAMERA_VSYNC:
if (VSYNC)
mid_cam_state <= CAMERA_VSYNC;
else
mid_cam_state <= CAMERA_WAIT_HREF;
CAMERA_WAIT_HREF:
if (HREF_UP)
begin
mid_cam_state <= CAMERA_H0;
write_data0_1 <= D_MID;
end
else
begin
if (VSYNC)
mid_cam_state <= CAMERA_IDLE;
else
mid_cam_state <= CAMERA_WAIT_HREF;
end
CAMERA_H0:
mid_cam_state <= CAMERA_H1;
CAMERA_H1:
begin
mid_cam_state <= CAMERA_H2;
write_data1_0 <= D_MID;
end
CAMERA_H2:
mid_cam_state <= CAMERA_H3;
CAMERA_H3:
begin
mid_cam_state <= CAMERA_H4;
write_data1_3 <= D_MID;
end
CAMERA_H4:
mid_cam_state <= CAMERA_H5;
CAMERA_H5:
begin
mid_cam_state <= CAMERA_H6;
write_data2_2 <= D_MID;
end
CAMERA_H6:
mid_cam_state <= CAMERA_H7;
CAMERA_H7:
if (HREF_MID)
begin
mid_cam_state <= CAMERA_H0;
write_data0_1 <= D_MID;
end
else
begin
mid_cam_state <= CAMERA_WAIT_HREF;
end
default:
mid_cam_state <= CAMERA_IDLE;
endcase
end
end
`ifdef CONFIG_RISING_EDGE_CLK
always @(posedge RESET or posedge CLK) begin
`else //CONFIG_FALLING_EDGE_CLK
always @(posedge RESET or negedge CLK) begin
`endif
if (RESET)
begin
dn_cam_state <= CAMERA_IDLE;
end
else
begin
case (dn_cam_state)
CAMERA_IDLE:
if (TRIG)
dn_cam_state <= CAMERA_WAIT_VSYNC;
else
dn_cam_state <= CAMERA_IDLE;
CAMERA_WAIT_VSYNC:
if (VSYNC)
dn_cam_state <= CAMERA_VSYNC;
else
dn_cam_state <= CAMERA_WAIT_VSYNC;
CAMERA_VSYNC:
if (VSYNC)
dn_cam_state <= CAMERA_VSYNC;
else
dn_cam_state <= CAMERA_WAIT_HREF;
CAMERA_WAIT_HREF:
if (HREF_DN)
begin
dn_cam_state <= CAMERA_H0;
write_data0_0 <= D_DN;
end
else
begin
if (VSYNC)
dn_cam_state <= CAMERA_IDLE;
else
dn_cam_state <= CAMERA_WAIT_HREF;
end
CAMERA_H0:
dn_cam_state <= CAMERA_H1;
CAMERA_H1:
begin
dn_cam_state <= CAMERA_H2;
write_data0_3 <= D_DN;
end
CAMERA_H2:
dn_cam_state <= CAMERA_H3;
CAMERA_H3:
begin
dn_cam_state <= CAMERA_H4;
write_data1_2 <= D_DN;
end
CAMERA_H4:
dn_cam_state <= CAMERA_H5;
CAMERA_H5:
begin
dn_cam_state <= CAMERA_H6;
write_data2_1 <= D_DN;
end
CAMERA_H6:
dn_cam_state <= CAMERA_H7;
CAMERA_H7:
if (HREF_DN)
begin
dn_cam_state <= CAMERA_H0;
write_data0_0 <= D_DN;
end
else
begin
dn_cam_state <= CAMERA_WAIT_HREF;
end
default:
dn_cam_state <= CAMERA_IDLE;
endcase
end
end
parameter DATA_HDLR_SIZE = 5;
parameter DATA_HDLR_IDLE = 5'b00001;
parameter DATA_HDLR_READ = 5'b00010;
parameter DATA_HDLR_WRITE_LOW = 5'b00100;
parameter DATA_HDLR_LOW_DONE = 5'b01000;
parameter DATA_HDLR_WRITE_HIGH = 5'b10000;
reg [15:0] read_data;
reg [DATA_HDLR_SIZE-1:0] data_hdlr_state;
`ifdef CONFIG_RISING_EDGE_CLK
always @(posedge RESET or posedge CLK) begin
`else // CONFIG_FALLING_EDGE_CLK
always @(posedge RESET or negedge CLK) begin
`endif
if (RESET)
begin
data_hdlr_state <= DATA_HDLR_IDLE;
nOE <= 1;
nSLWR <= 1;
end
else
begin
nOE <= 1;
nSLWR <= 1;
case (data_hdlr_state)
DATA_HDLR_IDLE:
if (read_flag)
begin
data_hdlr_state <= DATA_HDLR_READ;
nOE <= 0;
end
else
begin
data_hdlr_state <= DATA_HDLR_IDLE;
end
DATA_HDLR_READ:
begin
data_hdlr_state <= DATA_HDLR_WRITE_LOW;
read_data <= IO[31:16];
nSLWR <= 0;
FD <= IO[15:0];
end
DATA_HDLR_WRITE_LOW:
data_hdlr_state <= DATA_HDLR_LOW_DONE;
DATA_HDLR_LOW_DONE:
begin
data_hdlr_state <= DATA_HDLR_WRITE_HIGH;
nSLWR <= 0;
FD <= read_data;
end
DATA_HDLR_WRITE_HIGH:
if (read_flag)
begin
data_hdlr_state <= DATA_HDLR_READ;
nOE <= 0;
end
else
begin
data_hdlr_state <= DATA_HDLR_IDLE;
end
default:
data_hdlr_state <= DATA_HDLR_IDLE;
endcase
end
end
assign A = nOE ? write_addr[ADDR_SIZE-1:0] : read_addr[ADDR_SIZE-1:0];
assign IO = nOE ? (write_pend0 ? {write_data0_3, write_data0_2, write_data0_1, write_data0_0} :
(write_pend1 ? {write_data1_3, write_data1_2, write_data1_1, write_data1_0} :
{write_data2_3, write_data2_2, write_data2_1, write_data2_0})) : 'hz;
assign nPKTEND = 1;
endmodule
- Synthesis Option
Keep Hierarchy : No
Macro Preserve : Upcheck
- Fitting Option
I/O Voltage Standard : LVCMOS33
Logic Optimization : Density
- Synthesize Report
Summary
Design Name | entity |
Fitting Status | Successful |
Software Version | M.70d |
Device Used | XC2C256-7-TQ144 |
Date | 5-25-2011, 7:42PM |
RESOURCES SUMMARY
Macrocells Used | Pterms Used | Registers Used | Pins Used | Function Block Inputs Used |
---|---|---|---|---|
240/256 (94%) | 547/896 (62%) | 191/256 (75%) | 116/118 (99%) | 526/640 (83%) |
PIN RESOURCES
|
|
- Picture
Result
... But it can't work. If MCLK is set as 30Mhz, it works properly. It need replacement of CPLD with FPGA (maybe XC3S500E-208pin).
댓글 없음:
댓글 쓰기