 
- Xilinx ISE 11
- Spartan 3 (XC3S400-TQ144(-5))
- Verilog HDL
// User Constraint
NET "Pixel<0>" LOC = P99;
NET "Pixel<1>" LOC = P100;
NET "Pixel<2>" LOC = P102;
NET "Pixel<3>" LOC = P103;
NET "Pixel<4>" LOC = P104;
NET "Pixel<5>" LOC = P105;
NET "Pixel<6>" LOC = P107;
NET "Pixel<7>" LOC = P108;
NET "Href" LOC = P112;
NET "Vsync" LOC = P113;
NET "Trigger" LOC = P116;
NET "Reset" LOC = P118;
NET "Pclk" LOC = P124;
NET "nSLWR" LOC = P50;
NET "nFlagb" LOC = P51;
NET "FD<0>" LOC = P60;
NET "FD<1>" LOC = P63;
NET "FD<2>" LOC = P68;
NET "FD<3>" LOC = P69;
NET "FD<4>" LOC = P70;
NET "FD<5>" LOC = P73;
NET "FD<6>" LOC = P74;
NET "FD<7>" LOC = P76;
NET "FD<8>" LOC = P77;
NET "FD<9>" LOC = P78;
NET "FD<10>" LOC = P79;
NET "FD<11>" LOC = P80;
NET "FD<12>" LOC = P82;
NET "FD<13>" LOC = P83;
NET "FD<14>" LOC = P84;
NET "FD<15>" LOC = P85;
NET "nWE" LOC = P46;
NET "nOE" LOC = P44;
NET "Address<0>" LOC = P132;
NET "Address<1>" LOC = P135;
NET "Address<2>" LOC = P137;
NET "Address<3>" LOC = P140;
NET "Address<4>" LOC = P141;
NET "Address<5>" LOC = P1;
NET "Address<6>" LOC = P2;
NET "Address<7>" LOC = P4;
NET "Address<8>" LOC = P5;
NET "Address<9>" LOC = P6;
NET "Address<10>" LOC = P7;
NET "Address<11>" LOC = P8;
NET "Address<12>" LOC = P10;
NET "Address<13>" LOC = P11;
NET "Address<14>" LOC = P12;
NET "Address<15>" LOC = P13;
NET "Address<16>" LOC = P14;
NET "Address<17>" LOC = P15;
NET "Data<0>" LOC = P17;
NET "Data<1>" LOC = P18;
NET "Data<2>" LOC = P20;
NET "Data<3>" LOC = P21;
NET "Data<4>" LOC = P23;
NET "Data<5>" LOC = P24;
NET "Data<6>" LOC = P25;
NET "Data<7>" LOC = P26;
NET "Data<8>" LOC = P27;
NET "Data<9>" LOC = P28;
NET "Data<10>" LOC = P30;
NET "Data<11>" LOC = P31;
NET "Data<12>" LOC = P32;
NET "Data<13>" LOC = P33;
NET "Data<14>" LOC = P35;
NET "Data<15>" LOC = P36;
// Verilog Code
`timescale 1ns / 1ps
module isp_with_sram_and_usb(Reset, Trigger,
   Vsync, Href, Pclk, Pixel,
   nWE, nOE, Address, Data,
   /*Ifclk,*/ nFlagB, /*nPKTEND,*/ nSLWR, FD);
   parameter ADDR_SIZE = 18;
   parameter STATE_SIZE = 4;
   parameter IDLE = 4'b0001, WV = 4'b0010, WH = 4'b0100, H = 4'b1000;
   input Reset;
   input Trigger;
   input Vsync;
   input Href;
   input Pclk;
   input [7:0] Pixel;
   output reg nWE;
   output reg nOE;
   output [ADDR_SIZE-1:0] Address;
   inout [15:0] Data;
//    output Ifclk;
   input nFlagB;
//    output reg nPKTEND;
   output reg nSLWR;
   output reg [15:0] FD;
   wire Vsync, Href, Pclk; 
   // FSM for camera
   reg [STATE_SIZE-1:0] state;
   wire [STATE_SIZE-1:0] next_state;
   assign next_state = camera_fsm(state, Trigger, Vsync, Href);
   function [STATE_SIZE-1:0] camera_fsm;
       input [STATE_SIZE-1:0] state;
       input Trigger;
       input Vsync;
       input Href;
       case (state)
       IDLE:
           if (Trigger == 1'b1) camera_fsm = WV;
           else camera_fsm = IDLE;
       WV:
           if (Vsync == 1'b1) camera_fsm = WH;
           else camera_fsm = WV;
       WH:
           if (Href == 1'b1) camera_fsm = H;
           else camera_fsm = WH;
       H:
           if (Vsync == 1'b1) begin
               camera_fsm = IDLE;
           end else begin
               if (Href == 1'b1) camera_fsm = H;
               else camera_fsm = WH;
           end
       default:
           camera_fsm = IDLE;
       endcase
   endfunction
   always @(posedge Pclk) begin
       if (Reset == 1'b1) state <= IDLE;
       else state <= next_state;
   end
   // pixel toggling under H state
   reg pixel_toggle; // indicate the completion of word loading from pixel
   always @(posedge Pclk) begin
       if (Reset == 1'b1) begin
           pixel_toggle <= 1'b0;
       end else begin
           if (~|(state^H)) begin
               pixel_toggle <= pixel_toggle^1'b1;
           end else begin
               pixel_toggle <= 1'b0;
           end
       end
   end
   // even pixel container triggered by pixel toggle
   reg [7:0] byte_pixel;
   always @(posedge Pclk) begin
       if (Reset == 1'b1) begin
           byte_pixel <= 8'h0;
       end else begin
           if (pixel_toggle == 1'b0) byte_pixel <= Pixel;
       end
   end 
   reg [15:0] word_pixel;
   always @(posedge Pclk) begin
       if (Reset == 1'b1) begin
           word_pixel <= 16'h0;
       end else begin
           if (pixel_toggle == 1'b1) word_pixel <= {Pixel, byte_pixel};
       end
   end
   // FIFO
   // nWE; write word_pixel to memory
   //reg nWE;
   always @(posedge Pclk) begin
       if (Reset == 1'b1) begin
           nWE <= 1'b1;
       end else begin
           if (pixel_toggle == 1'b1) nWE <= 1'b0;
           else nWE <= 1'b1;
       end
   end
   reg [ADDR_SIZE:0] write_addr; // note MSB is not really address
   always @(posedge Pclk) begin
       if (Reset == 1'b1) begin
           write_addr <= 'h0;
       end else begin
           if (nWE == 1'b0) write_addr <= write_addr+1;
       end
   end
   reg [ADDR_SIZE:0] read_addr; // note MSB is not really address
   always @(posedge Pclk) begin
       if (Reset == 1'b1) begin
           read_addr <= 'h0;
       end else begin
           if (nOE == 1'b0) read_addr <= read_addr+1;
       end
   end
`ifdef USING_FULL_FLAG
   reg empty_flag;
   reg full_flag;
   always @(write_addr or read_addr) begin
       if (~|(write_addr[ADDR_SIZE-1:0]^read_addr[ADDR_SIZE-1:0])) begin
           if (~|(write_addr[ADDR_SIZE]^read_addr[ADDR_SIZE])) begin
               empty_flag <= 1'b1;
               full_flag <= 1'b0;
           end else begin
               empty_flag <= 1'b0;
               full_flag <= 1'b1;
           end
       end else begin
           empty_flag <= 1'b0;
           full_flag <= 1'b0;
       end
   end
`else
   reg empty_flag;
   always @(write_addr or read_addr) begin
       if (~|(write_addr[ADDR_SIZE:0]^read_addr[ADDR_SIZE:0])) empty_flag <= 1'b1;
       else empty_flag <= 1'b0;
   end
`endif
   //reg nOE;
   always @(posedge Pclk) begin
       if (Reset == 1'b1) begin
           nOE <= 1'b1;
       end else begin
           if (nOE == 1'b1 && pixel_toggle == 1'b0 && empty_flag == 1'b0 && nFlagB == 1'b1) begin
               nOE <= 1'b0;
           end else begin
               nOE <= 1'b1;
           end
       end
   end
   always @(posedge Pclk) begin
       if (Reset == 1'b1) begin
           nSLWR <= 1'b1;
           FD <= 16'hz;
       end else begin
           if (nOE == 1'b0) begin
               nSLWR <= 1'b0;
               FD <= Data;
           end else begin
               nSLWR <= 1'b1;
           end
       end
   end
   assign Address = (pixel_toggle == 1'b1 ? write_addr[ADDR_SIZE-1:0] :
read_addr[ADDR_SIZE-1:0]);
   assign Data = (pixel_toggle == 1'b1 ? word_pixel : 16'hz); 
//    assign Ifclk = Pclk; 
endmodule
=========================================================================
*                            Final Report                               *
=========================================================================
Clock Information:
------------------
-----------------------------------+------------------------+-------+
Clock Signal                       | Clock buffer(FF name)  | Load  |
-----------------------------------+------------------------+-------+
Pclk                               | BUFGP                  | 85    |
-----------------------------------+------------------------+-------+
Asynchronous Control Signals Information:
----------------------------------------
No asynchronous control signals found in this design
Timing Summary:
---------------
Speed Grade: -5
  Minimum period: 6.404ns (Maximum Frequency: 156.165MHz)
  Minimum input arrival time before clock: 5.696ns
  Maximum output required time after clock: 9.366ns
  Maximum combinational path delay: No path found
=========================================================================15>14>13>12>11>10>9>8>7>6>5>4>3>2>1>0>17>16>15>14>13>12>11>10>9>8>7>6>5>4>3>2>1>0>15>14>13>12>11>10>9>8>7>6>5>4>3>2>1>0>7>6>5>4>3>2>1>0>