2011년 5월 25일 수요일

3CCD Camera System

  • 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
Optimization Effor : High
Keep Hierarchy : No
Macro Preserve : Upcheck

  • Fitting Option
Implementation Template : Optimize Density
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
Signal Type Required Mapped
 Input  33  33
 Output  49  49
 Bidirectional  32  32
 GCK  1  1
 GTS  0  0
 GSR  1  1
Pin Type Used Total
 I/O   107  108
 GCK/IO  3  3
 GTS/IO  4  4
 GSR/IO  1  1
 CDR/IO  1  1
 DGE/IO   2  1



  • 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).

댓글 없음:

댓글 쓰기