Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

intermediate snapshot of FPGA construction

  • Loading branch information...
commit 7e84fe16183c8f068b0d45d5e63d6ffcaed9dbdf 1 parent 6d8012b
@bunnie authored
View
600 kovan1.srcs/constrs_1/imports/kovan1/kovan1.ucf
@@ -0,0 +1,600 @@
+### Autogenerated on 2012-Feb-16 16:25 by edifToUcf.py
+### Extracting designator U800 from EDIF netlist 01docmap.EDF
+
+# modified by bunnie
+
+###########################################
+# Setting VCCAUX for Spartan 6 TMDS
+###########################################
+CONFIG VCCAUX = 3.3;
+
+##################
+########## timing constraints
+##################
+
+## clocks
+NET "FPGA_SCLK" TNM_NET = "TNM_clk26";
+TIMESPEC "TS_clk26" = PERIOD "TNM_clk26" 26 MHz HIGH 50;
+
+
+##############
+# setup pins
+##############
+
+######### "camera" pins -- for image input from FPGA
+NET "CAM_D[0]" LOC = F9;
+NET "CAM_D[0]" IOSTANDARD = LVCMOS33;
+NET "CAM_D[1]" LOC = C10;
+NET "CAM_D[1]" IOSTANDARD = LVCMOS33;
+NET "CAM_D[2]" LOC = C5;
+NET "CAM_D[2]" IOSTANDARD = LVCMOS33;
+NET "CAM_D[3]" LOC = D9;
+NET "CAM_D[3]" IOSTANDARD = LVCMOS33;
+NET "CAM_D[4]" LOC = G9;
+NET "CAM_D[4]" IOSTANDARD = LVCMOS33;
+NET "CAM_D[5]" LOC = C4;
+NET "CAM_D[5]" IOSTANDARD = LVCMOS33;
+NET "CAM_D[6]" LOC = D8;
+NET "CAM_D[6]" IOSTANDARD = LVCMOS33;
+NET "CAM_D[7]" LOC = C8;
+NET "CAM_D[7]" IOSTANDARD = LVCMOS33;
+NET "CAM_HSYNC" LOC = C6;
+NET "CAM_HSYNC" IOSTANDARD = LVCMOS33;
+NET "CAM_MCLKO" LOC = B9;
+NET "CAM_MCLKO" IOSTANDARD = LVCMOS33;
+NET "CAM_PCLKI" LOC = D11;
+NET "CAM_PCLKI" IOSTANDARD = LVCMOS33;
+NET "CAM_VCLKO" LOC = C9;
+NET "CAM_VCLKO" IOSTANDARD = LVCMOS33;
+NET "CAM_VSYNC" LOC = D6;
+NET "CAM_VSYNC" IOSTANDARD = LVCMOS33;
+
+####### power subsystem
+# charger status pins
+NET "CHG_ACP" LOC = T5;
+NET "CHG_ACP" IOSTANDARD = LVCMOS33;
+NET "CHG_SHDN" LOC = R8;
+NET "CHG_SHDN" IOSTANDARD = LVCMOS33;
+
+###### HDMI control
+# HDMI CEC
+NET "CEC" LOC = N5;
+NET "CEC" IOSTANDARD = LVCMOS33;
+# HDMI DDC pins
+NET "DDC_SCL_LV_N" LOC = T4;
+NET "DDC_SCL_LV_N" IOSTANDARD = TMDS_33;
+NET "DDC_SDA_LV_N" LOC = R5;
+NET "DDC_SDA_LV_N" IOSTANDARD = TMDS_33;
+NET "DDC_SDA_PD" LOC = V4;
+NET "DDC_SDA_PD" IOSTANDARD = LVCMOS33;
+NET "DDC_SDA_PU" LOC = T3;
+NET "DDC_SDA_PU" IOSTANDARD = LVCMOS33;
+# HDMI hot plug detect ins
+NET "HDMI_HPD_LL_N" LOC = P6;
+NET "HDMI_HPD_LL_N" IOSTANDARD = LVCMOS33;
+NET "HPD_OVERRIDE" LOC = R3;
+NET "HPD_OVERRIDE" IOSTANDARD = LVCMOS33;
+# HDMI genlock feedback
+NET "VSYNC_STB" LOC = C7;
+NET "VSYNC_STB" IOSTANDARD = LVCMOS33;
+
+###### HDMI data
+
+NET "RX0_TMDS_N[0]" LOC = V11;
+NET "RX0_TMDS_N[0]" IOSTANDARD = TMDS_33;
+NET "RX0_TMDS_P[0]" LOC = U11;
+NET "RX0_TMDS_P[0]" IOSTANDARD = TMDS_33;
+NET "RX0_TMDS_N[1]" LOC = V13;
+NET "RX0_TMDS_N[1]" IOSTANDARD = TMDS_33;
+NET "RX0_TMDS_P[1]" LOC = U13;
+NET "RX0_TMDS_P[1]" IOSTANDARD = TMDS_33;
+NET "RX0_TMDS_N[2]" LOC = V16;
+NET "RX0_TMDS_N[2]" IOSTANDARD = TMDS_33;
+NET "RX0_TMDS_P[2]" LOC = U16;
+NET "RX0_TMDS_P[2]" IOSTANDARD = TMDS_33;
+NET "RX0_TMDS_N[3]" LOC = V10;
+NET "RX0_TMDS_N[3]" IOSTANDARD = TMDS_33;
+NET "RX0_TMDS_P[3]" LOC = U10;
+NET "RX0_TMDS_P[3]" IOSTANDARD = TMDS_33;
+NET "TX0_TMDS_N[0]" LOC = V6;
+NET "TX0_TMDS_N[0]" IOSTANDARD = TMDS_33;
+NET "TX0_TMDS_P[0]" LOC = T6;
+NET "TX0_TMDS_P[0]" IOSTANDARD = TMDS_33;
+NET "TX0_TMDS_N[1]" LOC = V7;
+NET "TX0_TMDS_N[1]" IOSTANDARD = TMDS_33;
+NET "TX0_TMDS_P[1]" LOC = U7;
+NET "TX0_TMDS_P[1]" IOSTANDARD = TMDS_33;
+NET "TX0_TMDS_N[2]" LOC = V8;
+NET "TX0_TMDS_N[2]" IOSTANDARD = TMDS_33;
+NET "TX0_TMDS_P[2]" LOC = U8;
+NET "TX0_TMDS_P[2]" IOSTANDARD = TMDS_33;
+NET "TX0_TMDS_N[3]" LOC = V5;
+NET "TX0_TMDS_N[3]" IOSTANDARD = TMDS_33;
+NET "TX0_TMDS_P[3]" LOC = U5;
+NET "TX0_TMDS_P[3]" IOSTANDARD = TMDS_33;
+
+
+########## i/o controller digital interfaces
+NET "DIG_ADC_CS[0]" LOC = M14;
+NET "DIG_ADC_CS[0]" IOSTANDARD = LVCMOS33;
+NET "DIG_ADC_CS[1]" LOC = T10;
+NET "DIG_ADC_CS[1]" IOSTANDARD = LVCMOS33;
+NET "DIG_ADC_IN" LOC = T13;
+NET "DIG_ADC_IN" IOSTANDARD = LVCMOS33;
+NET "DIG_ADC_OUT" LOC = R11;
+NET "DIG_ADC_OUT" IOSTANDARD = LVCMOS33;
+NET "DIG_ADC_SCLK" LOC = T11;
+NET "DIG_ADC_SCLK" IOSTANDARD = LVCMOS33;
+NET "DIG_CLR" LOC = P16;
+NET "DIG_CLR" IOSTANDARD = LVCMOS33;
+NET "DIG_IN" LOC = R10;
+NET "DIG_IN" IOSTANDARD = LVCMOS33;
+NET "DIG_OUT" LOC = L16;
+NET "DIG_OUT" IOSTANDARD = LVCMOS33;
+NET "DIG_RCLK" LOC = T14;
+NET "DIG_RCLK" IOSTANDARD = LVCMOS33;
+NET "DIG_SAMPLE" LOC = L15;
+NET "DIG_SAMPLE" IOSTANDARD = LVCMOS33;
+NET "DIG_SCLK" LOC = V14;
+NET "DIG_SCLK" IOSTANDARD = LVCMOS33;
+NET "DIG_SRLOAD" LOC = M16;
+NET "DIG_SRLOAD" IOSTANDARD = LVCMOS33;
+# motor controller direct interfaces
+NET "MBOT[0]" LOC = U17;
+NET "MBOT[0]" IOSTANDARD = LVCMOS33;
+NET "MTOP[0]" LOC = T17;
+NET "MTOP[0]" IOSTANDARD = LVCMOS33;
+NET "MBOT[1]" LOC = U18;
+NET "MBOT[1]" IOSTANDARD = LVCMOS33;
+NET "MTOP[1]" LOC = P15;
+NET "MTOP[1]" IOSTANDARD = LVCMOS33;
+NET "MBOT[2]" LOC = N16;
+NET "MBOT[2]" IOSTANDARD = LVCMOS33;
+NET "MTOP[2]" LOC = N15;
+NET "MTOP[2]" IOSTANDARD = LVCMOS33;
+NET "MBOT[3]" LOC = L14;
+NET "MBOT[3]" IOSTANDARD = LVCMOS33;
+NET "MTOP[3]" LOC = K14;
+NET "MTOP[3]" IOSTANDARD = LVCMOS33;
+NET "MOT_EN" LOC = P12;
+NET "MOT_EN" IOSTANDARD = LVCMOS33;
+NET "M_SERVO[0]" LOC = T8;
+NET "M_SERVO[0]" IOSTANDARD = LVCMOS33;
+NET "M_SERVO[1]" LOC = T9;
+NET "M_SERVO[1]" IOSTANDARD = LVCMOS33;
+NET "M_SERVO[2]" LOC = V9;
+NET "M_SERVO[2]" IOSTANDARD = LVCMOS33;
+NET "M_SERVO[3]" LOC = R7;
+NET "M_SERVO[3]" IOSTANDARD = LVCMOS33;
+
+
+######## external uart
+NET "EXT_TO_HOST_UART" LOC = D17;
+NET "EXT_TO_HOST_UART" IOSTANDARD = LVCMOS33;
+NET "HOST_TO_EXT_UART" LOC = V3;
+NET "HOST_TO_EXT_UART" IOSTANDARD = LVCMOS33;
+
+####### IR modulator input
+NET "IR_RX" LOC = E16; # was: GPIO_102
+NET "IR_RX" IOSTANDARD = LVCMOS33;
+
+####### pushbutton
+NET "INPUT_SW0" LOC = B16;
+NET "INPUT_SW0" IOSTANDARD = LVCMOS33;
+
+###### audio pass-through interface
+NET "I2S_CDCLK0" LOC = H18;
+NET "I2S_CDCLK0" IOSTANDARD = LVCMOS33;
+NET "I2S_CDCLK1" LOC = L13;
+NET "I2S_CDCLK1" IOSTANDARD = LVCMOS33;
+NET "I2S_CLK0" LOC = H17;
+NET "I2S_CLK0" IOSTANDARD = LVCMOS33;
+NET "I2S_CLK1" LOC = K16;
+NET "I2S_CLK1" IOSTANDARD = LVCMOS33;
+NET "I2S_DI0" LOC = F15;
+NET "I2S_DI0" IOSTANDARD = LVCMOS33;
+NET "I2S_DI1" LOC = C18;
+NET "I2S_DI1" IOSTANDARD = LVCMOS33;
+NET "I2S_DO0" LOC = G14;
+NET "I2S_DO0" IOSTANDARD = LVCMOS33;
+NET "I2S_DO1" LOC = C17;
+NET "I2S_DO1" IOSTANDARD = LVCMOS33;
+NET "I2S_LRCLK0" LOC = F16;
+NET "I2S_LRCLK0" IOSTANDARD = LVCMOS33;
+NET "I2S_LRCLK1" LOC = K15;
+NET "I2S_LRCLK1" IOSTANDARD = LVCMOS33;
+
+
+###### LCD interface -- includes pass-through and supplementary high-color bits
+NET "LCDO_B[3]" LOC = E18;
+NET "LCDO_B[3]" IOSTANDARD = LVCMOS33;
+NET "LCDO_B[4]" LOC = F17;
+NET "LCDO_B[4]" IOSTANDARD = LVCMOS33;
+NET "LCDO_B[5]" LOC = F18;
+NET "LCDO_B[5]" IOSTANDARD = LVCMOS33;
+NET "LCDO_B[6]" LOC = G18;
+NET "LCDO_B[6]" IOSTANDARD = LVCMOS33;
+NET "LCDO_B[7]" LOC = H12;
+NET "LCDO_B[7]" IOSTANDARD = LVCMOS33;
+NET "LCDO_DEN" LOC = K13;
+NET "LCDO_DEN" IOSTANDARD = LVCMOS33;
+NET "LCDO_DOTCLK" LOC = L12;
+NET "LCDO_DOTCLK" IOSTANDARD = LVCMOS33;
+NET "LCDO_G[2]" LOC = G13;
+NET "LCDO_G[2]" IOSTANDARD = LVCMOS33;
+NET "LCDO_G[3]" LOC = J13;
+NET "LCDO_G[3]" IOSTANDARD = LVCMOS33;
+NET "LCDO_G[4]" LOC = J18;
+NET "LCDO_G[4]" IOSTANDARD = LVCMOS33;
+NET "LCDO_G[5]" LOC = K12;
+NET "LCDO_G[5]" IOSTANDARD = LVCMOS33;
+NET "LCDO_G[6]" LOC = K18;
+NET "LCDO_G[6]" IOSTANDARD = LVCMOS33;
+NET "LCDO_G[6]" LOC = K17;
+NET "LCDO_G[7]" IOSTANDARD = LVCMOS33;
+NET "LCDO_HSYNC" LOC = P17;
+NET "LCDO_HSYNC" IOSTANDARD = LVCMOS33;
+NET "LCDO_R[2]" LOC = L18;
+NET "LCDO_R[2]" IOSTANDARD = LVCMOS33;
+NET "LCDO_R[3]" LOC = L17;
+NET "LCDO_R[3]" IOSTANDARD = LVCMOS33;
+NET "LCDO_R[4]" LOC = M18;
+NET "LCDO_R[4]" IOSTANDARD = LVCMOS33;
+NET "LCDO_R[5]" LOC = N18;
+NET "LCDO_R[5]" IOSTANDARD = LVCMOS33;
+NET "LCDO_R[6]" LOC = N17;
+NET "LCDO_R[6]" IOSTANDARD = LVCMOS33;
+NET "LCDO_R[7]" LOC = P18;
+NET "LCDO_R[7]" IOSTANDARD = LVCMOS33;
+NET "LCDO_RESET_N" LOC = D18;
+NET "LCDO_RESET_N" IOSTANDARD = TMDS_33;
+NET "LCDO_VSYNC" LOC = T18;
+NET "LCDO_VSYNC" IOSTANDARD = LVCMOS33;
+NET "LCD_B[0]" LOC = A11;
+NET "LCD_B[0]" IOSTANDARD = LVCMOS33;
+NET "LCD_B[1]" LOC = B11;
+NET "LCD_B[1]" IOSTANDARD = LVCMOS33;
+NET "LCD_B[2]" LOC = B2;
+NET "LCD_B[2]" IOSTANDARD = LVCMOS33;
+NET "LCD_B[3]" LOC = F13;
+NET "LCD_B[3]" IOSTANDARD = LVCMOS33;
+NET "LCD_B[4]" LOC = A12;
+NET "LCD_B[4]" IOSTANDARD = LVCMOS33;
+NET "LCD_B[5]" LOC = B12;
+NET "LCD_B[5]" IOSTANDARD = LVCMOS33;
+NET "LCD_DEN" LOC = A4;
+NET "LCD_DEN" IOSTANDARD = LVCMOS33;
+NET "LCD_G[0]" LOC = B3;
+NET "LCD_G[0]" IOSTANDARD = LVCMOS33;
+NET "LCD_G[1]" LOC = C14;
+NET "LCD_G[1]" IOSTANDARD = LVCMOS33;
+NET "LCD_G[2]" LOC = B8;
+NET "LCD_G[2]" IOSTANDARD = LVCMOS33;
+NET "LCD_G[3]" LOC = A8;
+NET "LCD_G[3]" IOSTANDARD = LVCMOS33;
+NET "LCD_G[4]" LOC = B4;
+NET "LCD_G[4]" IOSTANDARD = LVCMOS33;
+NET "LCD_G[5]" LOC = A2;
+NET "LCD_G[5]" IOSTANDARD = LVCMOS33;
+NET "LCD_HS" LOC = C15;
+NET "LCD_HS" IOSTANDARD = LVCMOS33;
+NET "LCD_R[0]" LOC = E13;
+NET "LCD_R[0]" IOSTANDARD = LVCMOS33;
+NET "LCD_R[1]" LOC = A3;
+NET "LCD_R[1]" IOSTANDARD = LVCMOS33;
+NET "LCD_R[2]" LOC = A6;
+NET "LCD_R[2]" IOSTANDARD = LVCMOS33;
+NET "LCD_R[3]" LOC = A5;
+NET "LCD_R[3]" IOSTANDARD = LVCMOS33;
+NET "LCD_R[4]" LOC = B6;
+NET "LCD_R[4]" IOSTANDARD = LVCMOS33;
+NET "LCD_R[5]" LOC = A7;
+NET "LCD_R[5]" IOSTANDARD = LVCMOS33;
+NET "LCD_SUPP[0]" LOC = H16;
+NET "LCD_SUPP[0]" IOSTANDARD = LVCMOS33;
+NET "LCD_SUPP[1]" LOC = H13;
+NET "LCD_SUPP[1]" IOSTANDARD = LVCMOS33;
+NET "LCD_SUPP[2]" LOC = A14;
+NET "LCD_SUPP[2]" IOSTANDARD = LVCMOS33;
+NET "LCD_SUPP[3]" LOC = B14;
+NET "LCD_SUPP[3]" IOSTANDARD = LVCMOS33;
+NET "LCD_SUPP[4]" LOC = J16;
+NET "LCD_SUPP[4]" IOSTANDARD = LVCMOS33;
+NET "LCD_SUPP[5]" LOC = H14;
+NET "LCD_SUPP[5]" IOSTANDARD = LVCMOS33;
+NET "LCD_VS" LOC = D14;
+NET "LCD_VS" IOSTANDARD = LVCMOS33;
+
+######## clock inputs
+NET "LCD_CLK_T" LOC = A9; # output to the CPU
+NET "LCD_CLK_T" IOSTANDARD = LVCMOS33;
+NET "OSC_CLK" LOC = A10; # 26 MHz input from the CPU
+NET "OSC_CLK" IOSTANDARD = LVCMOS33;
+
+########## FPGA to CPU primary interfaces
+# FPGA to cpu reset
+#NET "FPGA_RESET_N" LOC = V2;
+#NET "FPGA_RESET_N" IOSTANDARD = LVCMOS33;
+# A dedicated SSP, although likely to be used just as GPIO
+NET "FPGA_MISO" LOC = A16;
+NET "FPGA_MISO" IOSTANDARD = LVCMOS33;
+NET "FPGA_MOSI" LOC = F14;
+NET "FPGA_MOSI" IOSTANDARD = LVCMOS33;
+NET "FPGA_SCLK" LOC = C11;
+NET "FPGA_SCLK" IOSTANDARD = LVCMOS33;
+NET "FPGA_SYNC" LOC = A15;
+NET "FPGA_SYNC" IOSTANDARD = LVCMOS33;
+### FPGA to cpu I2C interfaces
+# this one is shared with audio, accelerometer, EEPROM, etc.
+NET "PWR_SCL" LOC = M13;
+NET "PWR_SCL" IOSTANDARD = LVCMOS33;
+NET "PWR_SDA" LOC = N14;
+NET "PWR_SDA" IOSTANDARD = LVCMOS33;
+# this one is dedicated to the FPGA
+NET "XI2CSCL" LOC = G16;
+NET "XI2CSCL" IOSTANDARD = LVCMOS33;
+NET "XI2CSDA" LOC = H15;
+NET "XI2CSDA" IOSTANDARD = LVCMOS33;
+
+#### this pin is for the LED. It's shared with HSWAPEN, so be careul with it.
+NET "FPGA_LED" LOC = D4;
+NET "FPGA_LED" IOSTANDARD = LVCMOS33;
+
+
+############################################################################
+## Memory Controller 3
+## Memory Device: DDR2_SDRAM->MT47H64M16XX-25
+## Frequency: 312.5 MHz
+## Time Period: 3200 ps
+## Supported Part Numbers: MT47H64M16HR-25
+############################################################################
+
+# NET "F_DDR2_VREF" LOC = C1;# M5 N3
+# NET "F_DDR2_VREF" IOSTANDARD = SSTL18_II;
+
+
+
+############################################################################
+## Clock constraints
+############################################################################
+NET "memc3_infrastructure_inst/sys_clk_ibufg" TNM_NET = "SYS_CLK3";
+TIMESPEC "TS_SYS_CLK3" = PERIOD "SYS_CLK3" 3.2 ns HIGH 50 %;
+############################################################################
+
+############################################################################
+## I/O TERMINATION
+############################################################################
+NET "mcb3_dram_dq[*]" IN_TERM = NONE;
+NET "mcb3_dram_dqs" IN_TERM = NONE;
+NET "mcb3_dram_dqs_n" IN_TERM = NONE;
+NET "mcb3_dram_udqs" IN_TERM = NONE;
+NET "mcb3_dram_udqs_n" IN_TERM = NONE;
+
+############################################################################
+# I/O STANDARDS
+############################################################################
+
+NET "mcb3_dram_dq[*]" IOSTANDARD = SSTL18_II ;
+NET "mcb3_dram_a[*]" IOSTANDARD = SSTL18_II ;
+NET "mcb3_dram_ba[*]" IOSTANDARD = SSTL18_II ;
+NET "mcb3_dram_dqs" IOSTANDARD = DIFF_SSTL18_II ;
+NET "mcb3_dram_udqs" IOSTANDARD = DIFF_SSTL18_II ;
+NET "mcb3_dram_dqs_n" IOSTANDARD = DIFF_SSTL18_II ;
+NET "mcb3_dram_udqs_n" IOSTANDARD = DIFF_SSTL18_II ;
+NET "mcb3_dram_ck" IOSTANDARD = DIFF_SSTL18_II ;
+NET "mcb3_dram_ck_n" IOSTANDARD = DIFF_SSTL18_II ;
+NET "mcb3_dram_cke" IOSTANDARD = SSTL18_II ;
+NET "mcb3_dram_ras_n" IOSTANDARD = SSTL18_II ;
+NET "mcb3_dram_cas_n" IOSTANDARD = SSTL18_II ;
+NET "mcb3_dram_we_n" IOSTANDARD = SSTL18_II ;
+NET "mcb3_dram_odt" IOSTANDARD = SSTL18_II ;
+NET "mcb3_dram_dm" IOSTANDARD = SSTL18_II ;
+NET "mcb3_dram_udm" IOSTANDARD = SSTL18_II ;
+NET "mcb3_rzq" IOSTANDARD = SSTL18_II ;
+NET "mcb3_zio" IOSTANDARD = SSTL18_II ;
+#NET "c3_sys_clk" IOSTANDARD = LVCMOS25 ;
+#NET "c3_sys_rst_i" IOSTANDARD = LVCMOS18 ;
+############################################################################
+# MCB 3
+# Pin Location Constraints for Clock, Masks, Address, and Controls
+############################################################################
+
+NET "mcb3_dram_a[0]" LOC = "J7" ;
+NET "mcb3_dram_a[10]" LOC = "F4" ;
+NET "mcb3_dram_a[11]" LOC = "D3" ;
+NET "mcb3_dram_a[12]" LOC = "G6" ;
+NET "mcb3_dram_a[1]" LOC = "J6" ;
+NET "mcb3_dram_a[2]" LOC = "H5" ;
+NET "mcb3_dram_a[3]" LOC = "L7" ;
+NET "mcb3_dram_a[4]" LOC = "F3" ;
+NET "mcb3_dram_a[5]" LOC = "H4" ;
+NET "mcb3_dram_a[6]" LOC = "H3" ;
+NET "mcb3_dram_a[7]" LOC = "H6" ;
+NET "mcb3_dram_a[8]" LOC = "D2" ;
+NET "mcb3_dram_a[9]" LOC = "D1" ;
+NET "mcb3_dram_ba[0]" LOC = "F2" ;
+NET "mcb3_dram_ba[1]" LOC = "F1" ;
+NET "mcb3_dram_ba[2]" LOC = "E1" ;
+NET "mcb3_dram_cas_n" LOC = "K5" ;
+NET "mcb3_dram_ck" LOC = "G3" ;
+NET "mcb3_dram_ck_n" LOC = "G1" ;
+NET "mcb3_dram_cke" LOC = "H7" ;
+NET "mcb3_dram_dm" LOC = "K3" ;
+NET "mcb3_dram_dq[0]" LOC = "L2" ;
+NET "mcb3_dram_dq[10]" LOC = "N2" ;
+NET "mcb3_dram_dq[11]" LOC = "N1" ;
+NET "mcb3_dram_dq[12]" LOC = "T2" ;
+NET "mcb3_dram_dq[13]" LOC = "T1" ;
+NET "mcb3_dram_dq[14]" LOC = "U2" ;
+NET "mcb3_dram_dq[15]" LOC = "U1" ;
+NET "mcb3_dram_dq[1]" LOC = "L1" ;
+NET "mcb3_dram_dq[2]" LOC = "K2" ;
+NET "mcb3_dram_dq[3]" LOC = "K1" ;
+NET "mcb3_dram_dq[4]" LOC = "H2" ;
+NET "mcb3_dram_dq[5]" LOC = "H1" ;
+NET "mcb3_dram_dq[6]" LOC = "J3" ;
+NET "mcb3_dram_dq[7]" LOC = "J1" ;
+NET "mcb3_dram_dq[8]" LOC = "M3" ;
+NET "mcb3_dram_dq[9]" LOC = "M1" ;
+NET "mcb3_dram_dqs" LOC = "L4" ;
+NET "mcb3_dram_dqs_n" LOC = "L3" ;
+NET "mcb3_dram_odt" LOC = "K6" ;
+NET "mcb3_dram_ras_n" LOC = "L5" ;
+#NET "c3_sys_clk" LOC = "R10" ;
+#NET "c3_sys_rst_i" LOC = "M8" ;
+NET "mcb3_dram_udm" LOC = "K4" ;
+NET "mcb3_dram_udqs" LOC = "P2" ;
+NET "mcb3_dram_udqs_n" LOC = "P1" ;
+NET "mcb3_dram_we_n" LOC = "E3" ;
+
+##################################################################################
+#RZQ is required for all MCB designs. Do not move the location #
+#of this pin for ES devices.For production devices, RZQ can be moved to any #
+#valid package pin within the MCB bank.For designs using Calibrated Input Termination, #
+#a 2R resistor should be connected between RZQand ground, where R is the desired#
+#input termination value. Otherwise, RZQ should be left as a no-connect (NC) pin.#
+##################################################################################
+NET "mcb3_rzq" LOC = "N4" ;
+##################################################################################
+#ZIO is only required for MCB designs using Calibrated Input Termination.#
+#ZIO can be moved to any valid package pin (i.e. bonded IO) within the#
+#MCB bank but must be left as a no-connect (NC) pin.#
+##################################################################################
+NET "mcb3_zio" LOC = "P4" ;
+
+
+# comment out and use xilinx auto-generated defaults
+# NET "F_M3_A0" LOC = J7;
+# NET "F_M3_A0" IOSTANDARD = SSTL18_II;
+# NET "F_M3_A1" LOC = J6;
+# NET "F_M3_A1" IOSTANDARD = SSTL18_II;
+# NET "F_M3_A10" LOC = F4;
+# NET "F_M3_A10" IOSTANDARD = SSTL18_II;
+# NET "F_M3_A11" LOC = D3;
+# NET "F_M3_A11" IOSTANDARD = SSTL18_II;
+# NET "F_M3_A12" LOC = G6;
+# NET "F_M3_A12" IOSTANDARD = SSTL18_II;
+# NET "F_M3_A13" LOC = F6;
+# NET "F_M3_A13" IOSTANDARD = SSTL18_II;
+# NET "F_M3_A14" LOC = F5;
+# NET "F_M3_A14" IOSTANDARD = SSTL18_II;
+# NET "F_M3_A2" LOC = H5;
+# NET "F_M3_A2" IOSTANDARD = SSTL18_II;
+# NET "F_M3_A3" LOC = L7;
+# NET "F_M3_A3" IOSTANDARD = SSTL18_II;
+# NET "F_M3_A4" LOC = F3;
+# NET "F_M3_A4" IOSTANDARD = SSTL18_II;
+# NET "F_M3_A5" LOC = H4;
+# NET "F_M3_A5" IOSTANDARD = SSTL18_II;
+# NET "F_M3_A6" LOC = H3;
+# NET "F_M3_A6" IOSTANDARD = SSTL18_II;
+# NET "F_M3_A7" LOC = H6;
+# NET "F_M3_A7" IOSTANDARD = SSTL18_II;
+# NET "F_M3_A8" LOC = D2;
+# NET "F_M3_A8" IOSTANDARD = SSTL18_II;
+# NET "F_M3_A9" LOC = D1;
+# NET "F_M3_A9" IOSTANDARD = SSTL18_II;
+# NET "F_M3_BA0" LOC = F2;
+# NET "F_M3_BA0" IOSTANDARD = SSTL18_II;
+# NET "F_M3_BA1" LOC = F1;
+# NET "F_M3_BA1" IOSTANDARD = SSTL18_II;
+# NET "F_M3_BA2" LOC = E1;
+# NET "F_M3_BA2" IOSTANDARD = SSTL18_II;
+# NET "F_M3_CAS_N" LOC = K5;
+# NET "F_M3_CAS_N" IOSTANDARD = SSTL18_II;
+# NET "F_M3_CKE" LOC = H7;
+# NET "F_M3_CKE" IOSTANDARD = SSTL18_II;
+# NET "F_M3_CLK_N" LOC = G1;
+# NET "F_M3_CLK_N" IOSTANDARD = DIFF_SSTL18_II;
+# NET "F_M3_CLK_P" LOC = G3;
+# NET "F_M3_CLK_P" IOSTANDARD = DIFF_SSTL18_II;
+# NET "F_M3_DQ0" LOC = L2;
+# NET "F_M3_DQ0" IOSTANDARD = SSTL18_II;
+# NET "F_M3_DQ1" LOC = L1;
+# NET "F_M3_DQ1" IOSTANDARD = SSTL18_II;
+# NET "F_M3_DQ10" LOC = N2;
+# NET "F_M3_DQ10" IOSTANDARD = SSTL18_II;
+# NET "F_M3_DQ11" LOC = N1;
+# NET "F_M3_DQ11" IOSTANDARD = SSTL18_II;
+# NET "F_M3_DQ12" LOC = T2;
+# NET "F_M3_DQ12" IOSTANDARD = SSTL18_II;
+# NET "F_M3_DQ13" LOC = T1;
+# NET "F_M3_DQ13" IOSTANDARD = SSTL18_II;
+# NET "F_M3_DQ14" LOC = U2;
+# NET "F_M3_DQ14" IOSTANDARD = SSTL18_II;
+# NET "F_M3_DQ15" LOC = U1;
+# NET "F_M3_DQ15" IOSTANDARD = SSTL18_II;
+# NET "F_M3_DQ2" LOC = K2;
+# NET "F_M3_DQ2" IOSTANDARD = SSTL18_II;
+# NET "F_M3_DQ3" LOC = K1;
+# NET "F_M3_DQ3" IOSTANDARD = SSTL18_II;
+# NET "F_M3_DQ4" LOC = H2;
+# NET "F_M3_DQ4" IOSTANDARD = SSTL18_II;
+# NET "F_M3_DQ5" LOC = H1;
+# NET "F_M3_DQ5" IOSTANDARD = SSTL18_II;
+# NET "F_M3_DQ6" LOC = J3;
+# NET "F_M3_DQ6" IOSTANDARD = SSTL18_II;
+# NET "F_M3_DQ7" LOC = J1;
+# NET "F_M3_DQ7" IOSTANDARD = SSTL18_II;
+# NET "F_M3_DQ8" LOC = M3;
+# NET "F_M3_DQ8" IOSTANDARD = SSTL18_II;
+# NET "F_M3_DQ9" LOC = M1;
+# NET "F_M3_DQ9" IOSTANDARD = SSTL18_II;
+# NET "F_M3_LDM" LOC = K3;
+# NET "F_M3_LDM" IOSTANDARD = SSTL18_II;
+# NET "F_M3_LDQS_N" LOC = L3;
+# NET "F_M3_LDQS_N" IOSTANDARD = DIFF_SSTL18_II;
+# NET "F_M3_LDQS_P" LOC = L4;
+# NET "F_M3_LDQS_P" IOSTANDARD = DIFF_SSTL18_II;
+# NET "F_M3_ODT" LOC = K6;
+# NET "F_M3_ODT" IOSTANDARD = SSTL18_II;
+# NET "F_M3_RAS_N" LOC = L5;
+# NET "F_M3_RAS_N" IOSTANDARD = SSTL18_II;
+# NET "F_M3_UDM" LOC = K4;
+# NET "F_M3_UDM" IOSTANDARD = SSTL18_II;
+# NET "F_M3_UDQS_N" LOC = P1;
+# NET "F_M3_UDQS_N" IOSTANDARD = DIFF_SSTL18_II;
+# NET "F_M3_UDQS_P" LOC = P2;
+# NET "F_M3_UDQS_P" IOSTANDARD = DIFF_SSTL18_II;
+# NET "F_M3_WE" LOC = E3;
+# NET "F_M3_WE" IOSTANDARD = SSTL18_II;
+# NET "F_RZQ" LOC = N4;
+# NET "F_RZQ" IOSTANDARD = SSTL18_II;
+
+
+#### autogenerated and not usable, but kept around for debugging reference only
+# FPGA JTAG -- do not use
+#NET "FPGA_TCK" LOC = A17;
+#NET "FPGA_TCK" IOSTANDARD = LVCMOS33;
+#NET "FPGA_TDI" LOC = D15;
+#NET "FPGA_TDI" IOSTANDARD = LVCMOS33;
+#NET "FPGA_TDO" LOC = D16;
+#NET "FPGA_TDO" IOSTANDARD = LVCMOS33;
+#NET "FPGA_TMS" LOC = B18;
+#NET "FPGA_TMS" IOSTANDARD = LVCMOS33;
+
+# configuration and control -- do not use
+#NET "FPGA_CCLK" LOC = R15;
+#NET "FPGA_CCLK" IOSTANDARD = LVCMOS33;
+#NET "FPGA_DIN" LOC = R13;
+#NET "FPGA_DIN" IOSTANDARD = LVCMOS33;
+#NET "FPGA_DONE" LOC = V17;
+#NET "FPGA_DONE" IOSTANDARD = LVCMOS33;
+#NET "FPGA_INIT_N" LOC = U3;
+#NET "FPGA_INIT_N" IOSTANDARD = TMDS_33;
+#NET "FPGA_M0" LOC = T15;
+#NET "FPGA_M0" IOSTANDARD = LVCMOS33;
+#NET "FPGA_M1" LOC = N12;
+#NET "FPGA_M1" IOSTANDARD = LVCMOS33;
+
+# power pins -- do not use
+# NET "GND" LOC = A1;# A18 B7 B13 C3 C16 D5 D10 E15 G2 G5 G12 G17 H8 H10 J4 J9 J11 J15 K8 K10 L9 L11 M2 M6 M17 N13 R1 R4 R9 R14 R16 R18 T16 U6 U12 V1 V18
+# NET "GND" IOSTANDARD = LVCMOS33;
+# NET "P1_2V" LOC = G7;# H9 H11 J8 J10 K9 K11 L8 L10 M7 M12
+# NET "P1_2V" IOSTANDARD = LVCMOS33;
+# NET "P1_8V" LOC = E2;# G4 J2 J5 M4 R2
+# NET "P1_8V" IOSTANDARD = LVCMOS33;
+# NET "P3_3V_F" LOC = B1;# B5 B10 B15 B17 D7 D13 E5 E9 E10 E14 E17 G10 G15 J12 J14 J17 K7 M9 M15 P5 P9 P10 P14 R6 R12 R17 U4 U9 U14
+# NET "P3_3V_F" IOSTANDARD = LVCMOS33;
+
+
View
932 kovan1.srcs/sources_1/imports/kovan1/common/i2c_slave.v
@@ -0,0 +1,932 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2011, Andrew "bunnie" Huang
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation and/or
+// other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+// A simple slave implementation. Oversampled for robustness.
+// The slave is extended into the snoop & surpress version for the DDC bus;
+// this is just a starting point for basic testing and also simple comms
+// with the CPU.
+//
+// i2c slave module requires the top level module to implement the IOBs
+// This is just to keep the tri-state easy to implemen across the hierarchy
+//
+// The code required on the top level is:
+// IOBUF #(.DRIVE(12), .SLEW("SLOW")) IOBUF_sda (.IO(SDA), .I(1'b0), .T(!SDA_pd));
+//
+///////////
+`timescale 1 ns / 1 ps
+
+module i2c_slave (
+ // external host interface
+ input wire SCL, // the SCL pin state
+ output wire SCL_pd, // signals to IOB to pull the SCL bus low
+ input wire SDA,
+ output reg SDA_pd,
+ output wire SDA_pu, // for overriding SDA...in the future.
+
+ input wire clk, // internal FPGA clock
+ input wire glbl_reset, // internal FPGA reset
+ // i2c configuration
+ input wire [7:0] i2c_device_addr,
+
+ // internal slave interface
+ output wire [7:0] reg_0,
+ output wire [7:0] reg_1,
+ input wire [7:0] reg_2,
+ output wire [7:0] reg_3,
+
+
+ output wire [7:0] reg_4,
+ output wire [7:0] reg_5,
+ output wire [7:0] reg_6,
+ output wire [7:0] reg_7,
+
+// output wire [7:0] reg_8,
+// output wire [7:0] reg_9,
+// output wire [7:0] reg_a,
+// output wire [7:0] reg_b,
+ input wire [7:0] reg_8,
+ input wire [7:0] reg_9,
+ input wire [7:0] reg_a,
+ input wire [7:0] reg_b,
+
+ output wire [7:0] reg_c,
+ output wire [7:0] reg_d,
+ output wire [7:0] reg_e,
+ output wire [7:0] reg_f,
+
+ input wire [7:0] reg_18, // note this is input now, not output
+
+ output wire [7:0] reg_19,
+ output wire [7:0] reg_1a,
+ output wire [7:0] reg_1b,
+ output wire [7:0] reg_1c,
+ output wire [7:0] reg_1d,
+ output wire [7:0] reg_1e,
+ output wire [7:0] reg_1f,
+
+ input wire [7:0] reg_10,
+
+ output wire [7:0] reg_11,
+ output wire [7:0] reg_12,
+
+ output wire [7:0] reg_13,
+ output wire [7:0] reg_14,
+ output wire [7:0] reg_15,
+ output wire [7:0] reg_16,
+ output wire [7:0] reg_17,
+
+ input wire [7:0] reg_20, // read-only bank starts here
+ input wire [7:0] reg_21,
+ input wire [7:0] reg_22,
+ input wire [7:0] reg_23,
+ input wire [7:0] reg_24,
+ input wire [7:0] reg_25,
+ input wire [7:0] reg_26,
+ input wire [7:0] reg_27,
+ input wire [7:0] reg_28,
+ input wire [7:0] reg_29,
+ input wire [7:0] reg_2a,
+ input wire [7:0] reg_2b,
+ input wire [7:0] reg_2c,
+ input wire [7:0] reg_2d,
+ input wire [7:0] reg_2e,
+ input wire [7:0] reg_2f,
+ input wire [7:0] reg_30,
+ input wire [7:0] reg_31,
+ input wire [7:0] reg_32,
+ input wire [7:0] reg_33,
+ input wire [7:0] reg_34,
+ input wire [7:0] reg_35,
+ input wire [7:0] reg_36,
+ input wire [7:0] reg_37,
+ input wire [7:0] reg_38,
+ input wire [7:0] reg_39,
+ input wire [7:0] reg_3a,
+ input wire [7:0] reg_3b,
+ input wire [7:0] reg_3c,
+ input wire [7:0] reg_3d,
+
+ input wire [7:0] reg_3e,
+ input wire [7:0] reg_3f,
+
+ output wire [7:0] reg_40,
+ input wire [7:0] reg_80,
+
+ input wire [7:0] reg_fc,
+ input wire [7:0] reg_fd,
+ input wire [7:0] reg_fe,
+ input wire [7:0] reg_ff
+ );
+
+ // internal reset
+ wire reset;
+ sync_reset i2c_slave_reset(
+ .clk(clk),
+ .glbl_reset(glbl_reset),
+ .reset(reset) );
+
+ /////// I2C physical layer components
+ /// SDA is stable when SCL is high.
+ /// If SDA moves while SCL is high, this is considered a start or stop condition.
+ ///
+ /// Otherwise, SDA can move around when SCL is low (this is where we suppress bits or
+ /// overdrive as needed). SDA is a wired-AND bus, so you only "drive" zero.
+ ///
+ /// In an oversampled implementation, a rising and falling edge de-glitcher is needed
+ /// for SCL and SDA.
+ ///
+
+ // rise fall time cycles computation:
+ // At 400kHz operation, 2.5us is a cycle. "chatter" from transition should be about
+ // 5% of total cycle time max (just rule of thumb), so 0.125us should be the equiv
+ // number of cycles.
+ // For the demo board, a 25 MHz clock is provided, and 0.125us ~ 4 cycles
+ // At 100kHz operation, 10us is a cycle, so 0.5us ~ 12 cycles
+ parameter TRF_CYCLES = 5'd4; // number of cycles for rise/fall time
+
+ // just some tie-offs for future functionality not yet implemented...
+ assign SDA_pu = 1'b0;
+ assign SCL_pd = 1'b0;
+
+ ////////////////
+ ///// protocol-level state machine
+ ////////////////
+ parameter I2C_START = 14'b1 << 0; // should only pass through this state for one cycle
+ parameter I2C_RESTART = 14'b1 << 1;
+ parameter I2C_DADDR = 14'b1 << 2;
+ parameter I2C_ACK_DADDR = 14'b1 << 3;
+ parameter I2C_ADDR = 14'b1 << 4;
+ parameter I2C_ACK_ADDR = 14'b1 << 5;
+ parameter I2C_WR_DATA = 14'b1 << 6;
+ parameter I2C_ACK_WR = 14'b1 << 7;
+ parameter I2C_END_WR = 14'b1 << 8;
+ parameter I2C_RD_DATA = 14'b1 << 9;
+ parameter I2C_ACK_RD = 14'b1 << 10;
+ parameter I2C_END_RD = 14'b1 << 11;
+ parameter I2C_END_RD2 = 14'b1 << 12;
+ parameter I2C_WAITSTOP = 14'b1 << 13;
+
+ parameter I2C_nSTATES = 14;
+
+ reg [(I2C_nSTATES-1):0] I2C_cstate = {{(I2C_nSTATES-1){1'b0}}, 1'b1}; //current and next states
+ reg [(I2C_nSTATES-1):0] I2C_nstate;
+
+//`define SIMULATION
+`ifdef SIMULATION
+ // synthesis translate_off
+ reg [8*20:1] I2C_state_ascii = "I2C_START ";
+ always @(I2C_cstate) begin
+ if (I2C_cstate == I2C_START) I2C_state_ascii <= "I2C_START ";
+ else if (I2C_cstate == I2C_RESTART) I2C_state_ascii <= "I2C_RESTART ";
+ else if (I2C_cstate == I2C_DADDR) I2C_state_ascii <= "I2C_DADDR ";
+ else if (I2C_cstate == I2C_ACK_DADDR) I2C_state_ascii <= "I2C_ACK_DADDR ";
+ else if (I2C_cstate == I2C_ADDR) I2C_state_ascii <= "I2C_ADDR ";
+ else if (I2C_cstate == I2C_ACK_ADDR) I2C_state_ascii <= "I2C_ACK_ADDR ";
+ else if (I2C_cstate == I2C_WR_DATA) I2C_state_ascii <= "I2C_WR_DATA ";
+ else if (I2C_cstate == I2C_ACK_WR) I2C_state_ascii <= "I2C_ACK_WR ";
+ else if (I2C_cstate == I2C_END_WR) I2C_state_ascii <= "I2C_END_WR ";
+ else if (I2C_cstate == I2C_RD_DATA) I2C_state_ascii <= "I2C_RD_DATA ";
+ else if (I2C_cstate == I2C_ACK_RD) I2C_state_ascii <= "I2C_ACK_RD ";
+ else if (I2C_cstate == I2C_END_RD) I2C_state_ascii <= "I2C_END_RD ";
+ else if (I2C_cstate == I2C_END_RD2) I2C_state_ascii <= "I2C_END_RD2 ";
+ else if (I2C_cstate == I2C_WAITSTOP) I2C_state_ascii <= "I2C_WAITSTOP ";
+ else I2C_state_ascii <= "WTF ";
+ end
+ // synthesis translate_on
+`endif
+
+ reg [3:0] I2C_bitcnt;
+ reg [7:0] I2C_addr;
+ reg [7:0] I2C_daddr;
+ reg [7:0] I2C_wdata;
+ reg [7:0] I2C_rdata;
+ reg I2C_reg_update;
+
+ ///// register block definitions
+ parameter RAM_WIDTH = 8;
+ parameter RAM_ADDR_BITS = 5; // note parameter width exception in reg_a* assign block below
+
+ reg [RAM_WIDTH-1:0] I2C_regblock [(2**RAM_ADDR_BITS)-1:0];
+ reg [RAM_WIDTH-1:0] I2C_regread_async;
+
+ wire [RAM_ADDR_BITS-1:0] I2C_ramaddr;
+
+ /// extended register set for Kovan
+ parameter EXT_RAM_WIDTH = 8;
+ parameter EXT_RAM_ADDR_BITS = 5; // note parameter width exception in reg_a* assign block below
+
+ reg [EXT_RAM_WIDTH-1:0] I2C_regblock_ext [(2**RAM_ADDR_BITS)-1:0];
+ reg [EXT_RAM_WIDTH-1:0] I2C_regread_async_ext;
+
+ wire [EXT_RAM_ADDR_BITS-1:0] I2C_ramaddr_ext;
+
+ ////////// code begins here
+ always @ (posedge clk) begin
+ if (reset || ((SCL_cstate == SCL_HIGH) && (SDA_cstate == SDA_RISE))) // stop condition always resets
+ I2C_cstate <= I2C_START;
+ else
+ I2C_cstate <= I2C_nstate;
+ end
+
+ always @ (*) begin
+ case (I2C_cstate) //synthesis parallel_case full_case
+ I2C_START: begin // wait for the start condition
+ I2C_nstate = ((SDA_cstate == SDA_FALL) && (SCL_cstate == SCL_HIGH)) ? I2C_DADDR : I2C_START;
+ end
+ I2C_RESTART: begin // repeated start moves immediately to DADDR
+ I2C_nstate = I2C_DADDR;
+ end
+ I2C_DADDR: begin // 8 bits to get the address
+ I2C_nstate = ((I2C_bitcnt > 4'h7) && (SCL_cstate == SCL_FALL)) ? I2C_ACK_DADDR : I2C_DADDR;
+ end
+ I2C_ACK_DADDR: begin // depending upon W/R bit state, go to one of two branches
+ I2C_nstate = (SCL_cstate == SCL_FALL) ?
+ (I2C_daddr[7:1] == i2c_device_addr[7:1]) ?
+ (I2C_daddr[0] == 1'b0 ? I2C_ADDR : I2C_RD_DATA) :
+ I2C_WAITSTOP : // !I2C_daddr match
+ I2C_ACK_DADDR; // !SCL_FALL
+ end
+
+ // device address branch
+ I2C_ADDR: begin
+ I2C_nstate = ((I2C_bitcnt > 4'h7) && (SCL_cstate == SCL_FALL)) ? I2C_ACK_ADDR : I2C_ADDR;
+ end
+ I2C_ACK_ADDR: begin
+ I2C_nstate = (SCL_cstate == SCL_FALL) ? I2C_WR_DATA : I2C_ACK_ADDR;
+ end
+
+ // write branch
+ I2C_WR_DATA: begin // 8 bits to get the write data
+ I2C_nstate = ((SDA_cstate == SDA_FALL) && (SCL_cstate == SCL_HIGH)) ? I2C_RESTART : // repeated start
+ ((I2C_bitcnt > 4'h7) && (SCL_cstate == SCL_FALL)) ? I2C_ACK_WR : I2C_WR_DATA;
+ end
+ I2C_ACK_WR: begin // trigger the ack response (pull SDA low until next falling edge)
+ // and stay in this state until the next falling edge of SCL
+ I2C_nstate = (SCL_cstate == SCL_FALL) ? I2C_END_WR : I2C_ACK_WR;
+ end
+ I2C_END_WR: begin // one-cycle state to update address+1, reset SDA pulldown
+ I2C_nstate = I2C_WR_DATA; // SCL is now low
+ end
+
+ // read branch
+ I2C_RD_DATA: begin // 8 bits to get the read data
+ I2C_nstate = ((SDA_cstate == SDA_FALL) && (SCL_cstate == SCL_HIGH)) ? I2C_RESTART : // repeated start
+ ((I2C_bitcnt > 4'h7) && (SCL_cstate == SCL_FALL)) ? I2C_ACK_RD : I2C_RD_DATA;
+ end
+ I2C_ACK_RD: begin // wait for an (n)ack response
+ // need to sample (n)ack on a rising edge
+ I2C_nstate = (SCL_cstate == SCL_RISE) ? I2C_END_RD : I2C_ACK_RD;
+ end
+ I2C_END_RD: begin // if nack, just go to start state (don't explicitly check stop event)
+ // single cycle state for adr+1 update
+ I2C_nstate = (SDA_cstate == SDA_LOW) ? I2C_END_RD2 : I2C_START;
+ end
+ I2C_END_RD2: begin // before entering I2C_RD_DATA, we need to have seen a falling edge.
+ I2C_nstate = (SCL_cstate == SCL_FALL) ? I2C_RD_DATA : I2C_END_RD2;
+ end
+
+ // we're not the addressed device, so we just idle until we see a stop
+ I2C_WAITSTOP: begin
+ I2C_nstate = (((SCL_cstate == SCL_HIGH) && (SDA_cstate == SDA_RISE))) ? // stop
+ I2C_START :
+ (((SCL_cstate == SCL_HIGH) && (SDA_cstate == SDA_FALL))) ? // or start
+ I2C_RESTART :
+ I2C_WAITSTOP;
+ end
+ endcase // case (cstate)
+ end
+
+ always @ (posedge clk) begin
+ if( reset ) begin
+ I2C_bitcnt <= 4'b0;
+ I2C_daddr <= 8'b0;
+ I2C_wdata <= 8'b0;
+ SDA_pd <= 1'b0;
+ I2C_reg_update <= 1'b0;
+ I2C_rdata <= 8'b0;
+ I2C_addr <= 8'b0; // this persists across transactions
+ end else begin
+ case (I2C_cstate) // synthesis parallel_case full_case
+ I2C_START: begin // everything in reset
+ I2C_bitcnt <= 4'b0;
+ I2C_daddr <= 8'b0;
+ I2C_wdata <= 8'b0;
+ I2C_rdata <= 8'b0;
+ SDA_pd <= 1'b0;
+ I2C_reg_update <= 1'b0;
+ I2C_addr <= I2C_addr;
+ end
+
+ I2C_RESTART: begin
+ I2C_bitcnt <= 4'b0;
+ I2C_daddr <= 8'b0;
+ I2C_wdata <= 8'b0;
+ I2C_rdata <= 8'b0;
+ SDA_pd <= 1'b0;
+ I2C_reg_update <= 1'b0;
+ I2C_addr <= I2C_addr;
+ end
+
+ // get my i2c device address (am I being talked to?)
+ I2C_DADDR: begin // shift in the address on rising edges of clock
+ if( SCL_cstate == SCL_RISE ) begin
+ I2C_bitcnt <= I2C_bitcnt + 4'b1;
+ I2C_daddr[7] <= I2C_daddr[6];
+ I2C_daddr[6] <= I2C_daddr[5];
+ I2C_daddr[5] <= I2C_daddr[4];
+ I2C_daddr[4] <= I2C_daddr[3];
+ I2C_daddr[3] <= I2C_daddr[2];
+ I2C_daddr[2] <= I2C_daddr[1];
+ I2C_daddr[1] <= I2C_daddr[0];
+ I2C_daddr[0] <= (SDA_cstate == SDA_HIGH) ? 1'b1 : 1'b0;
+ end else begin // we're oversampled so we need a hold-state gutter
+ I2C_bitcnt <= I2C_bitcnt;
+ I2C_daddr <= I2C_daddr;
+ end // else: !if( SCL_cstate == SCL_RISE )
+ SDA_pd <= 1'b0;
+ I2C_wdata <= 8'b0;
+ I2C_rdata <= 8'b0;
+ I2C_reg_update <= 1'b0;
+ I2C_addr <= I2C_addr;
+ end // case: I2C_DADDR
+ I2C_ACK_DADDR: begin
+ SDA_pd <= 1'b1; // active pull down ACK
+ I2C_daddr <= I2C_daddr;
+ I2C_bitcnt <= 4'b0;
+ I2C_wdata <= 8'b0;
+ I2C_rdata <= I2C_regread_async;
+ I2C_reg_update <= 1'b0;
+ I2C_addr <= I2C_addr;
+ end
+
+ // get my i2c "write" address (what we want to access inside me)
+ I2C_ADDR: begin
+ if( SCL_cstate == SCL_RISE ) begin
+ I2C_bitcnt <= I2C_bitcnt + 4'b1;
+ I2C_addr[7] <= I2C_addr[6];
+ I2C_addr[6] <= I2C_addr[5];
+ I2C_addr[5] <= I2C_addr[4];
+ I2C_addr[4] <= I2C_addr[3];
+ I2C_addr[3] <= I2C_addr[2];
+ I2C_addr[2] <= I2C_addr[1];
+ I2C_addr[1] <= I2C_addr[0];
+ I2C_addr[0] <= (SDA_cstate == SDA_HIGH) ? 1'b1 : 1'b0;
+ end else begin // we're oversampled so we need a hold-state gutter
+ I2C_bitcnt <= I2C_bitcnt;
+ I2C_addr <= I2C_addr;
+ end // else: !if( SCL_cstate == SCL_RISE )
+ SDA_pd <= 1'b0;
+ I2C_wdata <= 8'b0;
+ I2C_rdata <= 8'b0;
+ I2C_reg_update <= 1'b0;
+ I2C_daddr <= I2C_daddr;
+ end // case: I2C_ADDR
+ I2C_ACK_ADDR: begin
+ SDA_pd <= 1'b1; // active pull down ACK
+ I2C_daddr <= I2C_daddr;
+ I2C_bitcnt <= 4'b0;
+ I2C_wdata <= 8'b0;
+ I2C_rdata <= I2C_regread_async; // update my read data here
+ I2C_reg_update <= 1'b0;
+ I2C_addr <= I2C_addr;
+ end
+
+
+ // write branch
+ I2C_WR_DATA: begin // shift in data on rising edges of clock
+ if( SCL_cstate == SCL_RISE ) begin
+ I2C_bitcnt <= I2C_bitcnt + 4'b1;
+ I2C_wdata[7] <= I2C_wdata[6];
+ I2C_wdata[6] <= I2C_wdata[5];
+ I2C_wdata[5] <= I2C_wdata[4];
+ I2C_wdata[4] <= I2C_wdata[3];
+ I2C_wdata[3] <= I2C_wdata[2];
+ I2C_wdata[2] <= I2C_wdata[1];
+ I2C_wdata[1] <= I2C_wdata[0];
+ I2C_wdata[0] <= (SDA_cstate == SDA_HIGH) ? 1'b1 : 1'b0;
+ end else begin
+ I2C_bitcnt <= I2C_bitcnt; // hold state gutter
+ I2C_wdata <= I2C_wdata;
+ end // else: !if( SCL_cstate == SCL_RISE )
+ SDA_pd <= 1'b0;
+ I2C_daddr <= I2C_daddr;
+ I2C_reg_update <= 1'b0;
+ I2C_rdata <= I2C_rdata;
+ I2C_addr <= I2C_addr;
+ end // case: I2C_WR_DATA
+ I2C_ACK_WR: begin
+ SDA_pd <= 1'b1; // active pull down ACK
+ I2C_daddr <= I2C_daddr;
+ I2C_bitcnt <= 4'b0;
+ I2C_wdata <= I2C_wdata;
+ I2C_reg_update <= 1'b1; // write the data now (over and over again while in state)
+ I2C_rdata <= I2C_rdata;
+ I2C_addr <= I2C_addr;
+ end
+ I2C_END_WR: begin
+ SDA_pd <= 1'b0; // let SDA rise (host may look for this to know ack is done
+ I2C_addr <= I2C_addr + 8'b1; // this is a one-cycle state so this is safe
+ I2C_bitcnt <= 4'b0;
+ I2C_wdata <= 8'b0;
+ I2C_rdata <= I2C_rdata;
+ I2C_reg_update <= 1'b0;
+ I2C_daddr <= I2C_daddr;
+ end
+
+ // read branch
+ I2C_RD_DATA: begin // shift out data on falling edges of clock
+ SDA_pd <= I2C_rdata[7] ? 1'b0 : 1'b1;
+ if( SCL_cstate == SCL_RISE ) begin
+ I2C_bitcnt <= I2C_bitcnt + 4'b1;
+ end else begin
+ I2C_bitcnt <= I2C_bitcnt; // hold state gutter
+ end
+
+ if( SCL_cstate == SCL_FALL ) begin
+ I2C_rdata[7] <= I2C_rdata[6];
+ I2C_rdata[6] <= I2C_rdata[5];
+ I2C_rdata[5] <= I2C_rdata[4];
+ I2C_rdata[4] <= I2C_rdata[3];
+ I2C_rdata[3] <= I2C_rdata[2];
+ I2C_rdata[2] <= I2C_rdata[1];
+ I2C_rdata[1] <= I2C_rdata[0];
+ I2C_rdata[0] <= 1'b0;
+ end else begin
+ I2C_rdata <= I2C_rdata;
+ end // else: !if( SCL_cstate == SCL_RISE )
+ I2C_daddr <= I2C_daddr;
+ I2C_reg_update <= 1'b0;
+ I2C_wdata <= I2C_wdata;
+ I2C_addr <= I2C_addr;
+ end // case: I2C_RD_DATA
+ I2C_ACK_RD: begin
+ SDA_pd <= 1'b0; // in ack state don't pull down, we are listening to host
+ I2C_daddr <= I2C_daddr;
+ I2C_bitcnt <= 4'b0;
+ I2C_rdata <= I2C_rdata;
+ I2C_reg_update <= 1'b0;
+ I2C_wdata <= I2C_wdata;
+ I2C_addr <= I2C_addr;
+ end
+ I2C_END_RD: begin
+ SDA_pd <= 1'b0; // let SDA rise (host may look for this to know ack is done
+ I2C_addr <= I2C_addr + 8'b1; // this is a one-cycle state so this is safe
+ I2C_bitcnt <= 4'b0;
+ I2C_rdata <= I2C_rdata;
+ I2C_reg_update <= 1'b0;
+ I2C_wdata <= I2C_wdata;
+ I2C_daddr <= I2C_daddr;
+ end
+ I2C_END_RD2: begin
+ SDA_pd <= 1'b0;
+ I2C_daddr <= 8'b0;
+ I2C_bitcnt <= 4'b0;
+ I2C_rdata <= I2C_regread_async; // update my read data here
+ I2C_reg_update <= 1'b0;
+ I2C_wdata <= I2C_wdata;
+ I2C_addr <= I2C_addr;
+ end
+
+ I2C_WAITSTOP: begin
+ SDA_pd <= 1'b0;
+ I2C_daddr <= 8'b0;
+ I2C_bitcnt <= 4'b0;
+ I2C_rdata <= I2C_rdata;
+ I2C_reg_update <= 1'b0;
+ I2C_wdata <= I2C_wdata;
+ I2C_addr <= I2C_addr;
+ end
+ endcase // case (cstate)
+ end // else: !if( reset )
+ end // always @ (posedge clk or posedge reset)
+
+
+
+
+ ////////////////////////////////////
+ ///// register bank management /////
+ ////////////////////////////////////
+
+ // main block update (write from I2C)
+ always @(posedge clk) begin
+ if (I2C_reg_update && ((I2C_addr[6] == 1'b0) && (I2C_addr[7] == 1'b0))) begin // I2C_addr < 8'h40
+ I2C_regblock[I2C_ramaddr] <= I2C_wdata;
+ end
+ end
+ assign I2C_ramaddr = I2C_addr[RAM_ADDR_BITS-1:0];
+
+ // extended block update (write from I2C)
+ wire [7:0] extaddr_int;
+ assign extaddr_int = I2C_addr[7:0] - 8'h40;
+ assign I2C_ramaddr_ext[EXT_RAM_ADDR_BITS-1:0] = extaddr_int[EXT_RAM_ADDR_BITS-1:0];
+
+ always @(posedge clk) begin
+ if (I2C_reg_update && ((I2C_addr[6] == 1'b1) || (I2C_addr[7] == 1'b1)) ) begin // I2C_addr >= 8'h40
+ I2C_regblock_ext[I2C_ramaddr_ext] <= I2C_wdata;
+ end
+ end
+
+
+ ///////// ick, had to hard-code the width against RAM_ADDR_BITS which is parameterized
+ assign reg_0 = I2C_regblock[5'h0];
+ assign reg_1 = I2C_regblock[5'h1];
+// assign reg_2 = I2C_regblock[5'h2];
+ assign reg_3 = I2C_regblock[5'h3];
+ assign reg_4 = I2C_regblock[5'h4];
+ assign reg_5 = I2C_regblock[5'h5];
+ assign reg_6 = I2C_regblock[5'h6];
+ assign reg_7 = I2C_regblock[5'h7];
+// assign reg_8 = I2C_regblock[5'h8];
+// assign reg_9 = I2C_regblock[5'h9];
+// assign reg_a = I2C_regblock[5'ha];
+// assign reg_b = I2C_regblock[5'hb];
+
+ assign reg_c = I2C_regblock[5'hc];
+ assign reg_d = I2C_regblock[5'hd];
+ assign reg_e = I2C_regblock[5'he];
+ assign reg_f = I2C_regblock[5'hf];
+
+ assign reg_11 = I2C_regblock[5'h11];
+ assign reg_12 = I2C_regblock[5'h12];
+
+ assign reg_13 = I2C_regblock[5'h13];
+ assign reg_14 = I2C_regblock[5'h14];
+
+ assign reg_15 = I2C_regblock[5'h15];
+ assign reg_16 = I2C_regblock[5'h16];
+ assign reg_17 = I2C_regblock[5'h17];
+
+// assign reg_18 = I2C_regblock[5'h18];
+
+ assign reg_19 = I2C_regblock[5'h19]; // lsb of Km
+ assign reg_1a = I2C_regblock[5'h1a];
+ assign reg_1b = I2C_regblock[5'h1b];
+ assign reg_1c = I2C_regblock[5'h1c];
+ assign reg_1d = I2C_regblock[5'h1d];
+ assign reg_1e = I2C_regblock[5'h1e];
+ assign reg_1f = I2C_regblock[5'h1f]; // msb of Km
+
+ /// extended block
+ assign reg_40 = I2C_regblock_ext[5'h0]; // note the renumbering -- it's (target address - 0x40)
+
+
+ always @(*) begin
+ case (I2C_addr[7:0])
+ 8'h2: begin
+ I2C_regread_async = reg_2;
+ end
+ 8'h8: begin
+ I2C_regread_async = reg_8;
+ end
+ 8'h9: begin
+ I2C_regread_async = reg_9;
+ end
+ 8'ha: begin
+ I2C_regread_async = reg_a;
+ end
+ 8'hb: begin
+ I2C_regread_async = reg_b;
+ end
+
+ 8'h10: begin
+ I2C_regread_async = reg_10;
+ end
+ 8'h18: begin
+ I2C_regread_async = reg_18;
+ end
+
+ 8'h20: begin
+ I2C_regread_async = reg_20;
+ end
+ 8'h21: begin
+ I2C_regread_async = reg_21;
+ end
+ 8'h22: begin
+ I2C_regread_async = reg_22;
+ end
+ 8'h23: begin
+ I2C_regread_async = reg_23;
+ end
+ 8'h24: begin
+ I2C_regread_async = reg_24;
+ end
+ 8'h25: begin
+ I2C_regread_async = reg_25;
+ end
+ 8'h26: begin
+ I2C_regread_async = reg_26;
+ end
+ 8'h27: begin
+ I2C_regread_async = reg_27;
+ end
+ 8'h28: begin
+ I2C_regread_async = reg_28;
+ end
+ 8'h29: begin
+ I2C_regread_async = reg_29;
+ end
+ 8'h2a: begin
+ I2C_regread_async = reg_2a;
+ end
+ 8'h2b: begin
+ I2C_regread_async = reg_2b;
+ end
+ 8'h2c: begin
+ I2C_regread_async = reg_2c;
+ end
+ 8'h2d: begin
+ I2C_regread_async = reg_2d;
+ end
+ 8'h2e: begin
+ I2C_regread_async = reg_2e;
+ end
+ 8'h2f: begin
+ I2C_regread_async = reg_2f;
+ end
+
+ 8'h30: begin
+ I2C_regread_async = reg_30;
+ end
+ 8'h31: begin
+ I2C_regread_async = reg_31;
+ end
+ 8'h32: begin
+ I2C_regread_async = reg_32;
+ end
+ 8'h33: begin
+ I2C_regread_async = reg_33;
+ end
+ 8'h34: begin
+ I2C_regread_async = reg_34;
+ end
+ 8'h35: begin
+ I2C_regread_async = reg_35;
+ end
+ 8'h36: begin
+ I2C_regread_async = reg_36;
+ end
+ 8'h37: begin
+ I2C_regread_async = reg_37;
+ end
+
+ 8'h38: begin
+ I2C_regread_async = reg_38;
+ end
+ 8'h39: begin
+ I2C_regread_async = reg_39;
+ end
+ 8'h3a: begin
+ I2C_regread_async = reg_3a;
+ end
+ 8'h3b: begin
+ I2C_regread_async = reg_3b;
+ end
+ 8'h3c: begin
+ I2C_regread_async = reg_3c;
+ end
+ 8'h3d: begin
+ I2C_regread_async = reg_3d;
+ end
+
+ 8'h3e: begin
+ I2C_regread_async = reg_3e;
+ end
+ 8'h3f: begin
+ I2C_regread_async = reg_3f;
+ end
+
+ 8'h80: begin
+ I2C_regread_async = reg_80;
+ end
+
+ 8'hfc: begin
+ I2C_regread_async = reg_fc;
+ end
+ 8'hfd: begin
+ I2C_regread_async = reg_fd;
+ end
+ 8'hfe: begin
+ I2C_regread_async = reg_fe;
+ end
+ 8'hff: begin
+ I2C_regread_async = reg_ff;
+ end
+ default: begin
+ if( (I2C_addr[6] == 1'b0) && (I2C_addr[7] == 1'b0) ) begin
+ I2C_regread_async = I2C_regblock[I2C_ramaddr];
+ end else begin
+ I2C_regread_async = I2C_regblock_ext[I2C_ramaddr_ext];
+ end
+ end
+ endcase // case I2C_ramaddr
+ end // always @ (*)
+
+
+
+ ///////////////////////////////////////////////////////////////
+ /////////// low level state machines //////////////////////////
+ ///////////////////////////////////////////////////////////////
+
+
+ ////////////////
+ ///// SCL low-level sampling state machine
+ ////////////////
+ parameter SCL_HIGH = 4'b1 << 0; // should only pass through this state for one cycle
+ parameter SCL_FALL = 4'b1 << 1;
+ parameter SCL_LOW = 4'b1 << 2;
+ parameter SCL_RISE = 4'b1 << 3;
+ parameter SCL_nSTATES = 4;
+
+ reg [(SCL_nSTATES-1):0] SCL_cstate = {{(SCL_nSTATES-1){1'b0}}, 1'b1}; //current and next states
+ reg [(SCL_nSTATES-1):0] SCL_nstate;
+
+//`define SIMULATION
+`ifdef SIMULATION
+ // synthesis translate_off
+ reg [8*20:1] SCL_state_ascii = "SCL_HIGH ";
+
+ always @(SCL_cstate) begin
+ if (SCL_cstate == SCL_HIGH) SCL_state_ascii <= "SCL_HIGH ";
+ else if (SCL_cstate == SCL_FALL) SCL_state_ascii <= "SCL_FALL ";
+ else if (SCL_cstate == SCL_LOW ) SCL_state_ascii <= "SCL_LOW ";
+ else if (SCL_cstate == SCL_RISE) SCL_state_ascii <= "SCL_RISE ";
+ else SCL_state_ascii <= "WTF ";
+ end
+ // synthesis translate_on
+`endif
+
+ reg [4:0] SCL_rfcnt;
+ reg SCL_s, SCL_sync;
+ reg SDA_s, SDA_sync;
+
+ always @ (posedge clk) begin
+ if (reset)
+ SCL_cstate <= SCL_HIGH; // always start here even if it's wrong -- easier to test
+ else
+ SCL_cstate <= SCL_nstate;
+ end
+
+ always @ (*) begin
+ case (SCL_cstate) //synthesis parallel_case full_case
+ SCL_HIGH: begin
+ SCL_nstate = ((SCL_rfcnt > TRF_CYCLES) && (SCL_sync == 1'b0)) ? SCL_FALL : SCL_HIGH;
+ end
+ SCL_FALL: begin
+ SCL_nstate = SCL_LOW;
+ end
+ SCL_LOW: begin
+ SCL_nstate = ((SCL_rfcnt > TRF_CYCLES) && (SCL_sync == 1'b1)) ? SCL_RISE : SCL_LOW;
+ end
+ SCL_RISE: begin
+ SCL_nstate = SCL_HIGH;
+ end
+ endcase // case (cstate)
+ end // always @ (*)
+
+ always @ (posedge clk) begin
+ if( reset ) begin
+ SCL_rfcnt <= 5'b0;
+ end else begin
+ case (SCL_cstate) // synthesis parallel_case full_case
+ SCL_HIGH: begin
+ if( SCL_sync == 1'b1 ) begin
+ SCL_rfcnt <= 5'b0;
+ end else begin
+ SCL_rfcnt <= SCL_rfcnt + 5'b1;
+ end
+ end
+ SCL_FALL: begin
+ SCL_rfcnt <= 5'b0;
+ end
+ SCL_LOW: begin
+ if( SCL_sync == 1'b0 ) begin
+ SCL_rfcnt <= 5'b0;
+ end else begin
+ SCL_rfcnt <= SCL_rfcnt + 5'b1;
+ end
+ end
+ SCL_RISE: begin
+ SCL_rfcnt <= 5'b0;
+ end
+ endcase // case (cstate)
+ end // else: !if( reset )
+ end // always @ (posedge clk or posedge reset)
+
+
+ ////////////////
+ ///// SDA low-level sampling state machine
+ ////////////////
+ parameter SDA_HIGH = 4'b1 << 0; // should only pass through this state for one cycle
+ parameter SDA_FALL = 4'b1 << 1;
+ parameter SDA_LOW = 4'b1 << 2;
+ parameter SDA_RISE = 4'b1 << 3;
+ parameter SDA_nSTATES = 4;
+
+ reg [(SDA_nSTATES-1):0] SDA_cstate = {{(SDA_nSTATES-1){1'b0}}, 1'b1}; //current and next states
+ reg [(SDA_nSTATES-1):0] SDA_nstate;
+
+//`define SIMULATION
+`ifdef SIMULATION
+ // synthesis translate_off
+ reg [8*20:1] SDA_state_ascii = "SDA_HIGH ";
+
+ always @(SDA_cstate) begin
+ if (SDA_cstate == SDA_HIGH) SDA_state_ascii <= "SDA_HIGH ";
+ else if (SDA_cstate == SDA_FALL) SDA_state_ascii <= "SDA_FALL ";
+ else if (SDA_cstate == SDA_LOW ) SDA_state_ascii <= "SDA_LOW ";
+ else if (SDA_cstate == SDA_RISE) SDA_state_ascii <= "SDA_RISE ";
+ else SDA_state_ascii <= "WTF ";
+ end
+ // synthesis translate_on
+`endif
+
+ reg [4:0] SDA_rfcnt;
+
+ always @ (posedge clk) begin
+ if (reset)
+ SDA_cstate <= SDA_HIGH; // always start here even if it's wrong -- easier to test
+ else
+ SDA_cstate <= SDA_nstate;
+ end
+
+ always @ (*) begin
+ case (SDA_cstate) //synthesis parallel_case full_case
+ SDA_HIGH: begin
+ SDA_nstate = ((SDA_rfcnt > TRF_CYCLES) && (SDA_sync == 1'b0)) ? SDA_FALL : SDA_HIGH;
+ end
+ SDA_FALL: begin
+ SDA_nstate = SDA_LOW;
+ end
+ SDA_LOW: begin
+ SDA_nstate = ((SDA_rfcnt > TRF_CYCLES) && (SDA_sync == 1'b1)) ? SDA_RISE : SDA_LOW;
+ end
+ SDA_RISE: begin
+ SDA_nstate = SDA_HIGH;
+ end
+ endcase // case (cstate)
+ end // always @ (*)
+
+ always @ (posedge clk) begin
+ if( reset ) begin
+ SDA_rfcnt <= 5'b0;
+ end else begin
+ case (SDA_cstate) // synthesis parallel_case full_case
+ SDA_HIGH: begin
+ if( SDA_sync == 1'b1 ) begin
+ SDA_rfcnt <= 5'b0;
+ end else begin
+ SDA_rfcnt <= SDA_rfcnt + 5'b1;
+ end
+ end
+ SDA_FALL: begin
+ SDA_rfcnt <= 5'b0;
+ end
+ SDA_LOW: begin
+ if( SDA_sync == 1'b0 ) begin
+ SDA_rfcnt <= 5'b0;
+ end else begin
+ SDA_rfcnt <= SDA_rfcnt + 5'b1;
+ end
+ end
+ SDA_RISE: begin
+ SDA_rfcnt <= 5'b0;
+ end
+ endcase // case (cstate)
+ end // else: !if( reset )
+ end // always @ (posedge clk or posedge reset)
+
+
+
+ /////////////////////
+ /////// synchronizers
+ /////////////////////
+ always @ (posedge clk) begin
+ SCL_s <= SCL;
+ SCL_sync <= SCL_s;
+ SDA_s <= SDA;
+ SDA_sync <= SDA_s;
+ end // always @ (posedge clk or posedge reset)
+
+endmodule // i2c_slave
View
76 kovan1.srcs/sources_1/imports/kovan1/common/pwm.v
@@ -0,0 +1,76 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2011, Andrew "bunnie" Huang
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation and/or
+// other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+// this module does simple PWM modulation to create the "breathing" LED effect
+//
+
+`timescale 1 ns / 1 ps
+
+module pwm(
+ input wire clk812k, // use clock from device DNA block, 812.5kHz
+ output reg pwmout,
+ input wire [11:0] bright,
+ input wire [11:0] dim
+ );
+
+ reg [9:0] pwm_count;
+ reg pwmreg;
+ reg [11:0] interpolate;
+ reg countdn;
+ wire [9:0] interp;
+
+ always @(posedge clk812k) begin
+ if( interpolate[11:0] >= bright[11:0] ) begin
+ countdn <= 1;
+ end else if( interpolate[11:0] <= dim[11:0] ) begin
+ countdn <= 0;
+ end else begin
+ countdn <= countdn;
+ end
+
+ if( pwm_count[9:0] == 10'h0 ) begin
+ if( countdn == 1'b1 ) begin
+ interpolate[11:0] <= interpolate[11:0] - 12'b1;
+ end else begin
+ interpolate[11:0] <= interpolate[11:0] + 12'b1;
+ end
+ end else begin
+ interpolate[11:0] <= interpolate[11:0];
+ end
+
+ pwm_count[9:0] <= pwm_count[9:0] + 10'b1;
+
+ pwmreg <= (pwm_count[9:0] < interp[9:0]);
+ end // always @ (posedge clk812k)
+
+
+ assign interp[9:0] = interpolate[11:2];
+
+ always @(posedge clk812k) begin
+ // make it registered to ease up routing congestion to the edge
+ pwmout <= !pwmreg;
+ end
+
+endmodule // pwm
View
61 kovan1.srcs/sources_1/imports/kovan1/common/sync_reset.v
@@ -0,0 +1,61 @@
+////////////////////////////////////////////////
+// Copyright (c) 2012, Andrew "bunnie" Huang
+// (bunnie _aht_ bunniestudios "dote" com)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+////////////////////////////////////////////////
+
+/// according to Xilinx WP272, all flip flops are reset to a "known value"
+/// by GSR. You're supposed to trust that. Of course, this "known value"
+/// isn't very explicitly stated, searching through the xilinx manuals
+/// it seems everything defaults to 0 except for stuff that's presetable.
+
+/// anyways, this module generates a local, synchronized reset based upon
+/// a global reset. The idea is to instantiate one of these near every
+/// terminal reset sink, so as to avoid loading down a global reset network.
+
+/// this should optimize utilization and speed a bit, and also allow the
+/// synthesizer to get more aggressive about using larger primitives
+
+//////////
+// the input is the asychronous reset of interest
+// and the clock to synchronize it to
+// the output is a synchronized reset that is at least four clock cycles wide
+module sync_reset (
+ input wire glbl_reset, // async reset
+ input wire clk,
+ output wire reset
+ );
+
+ wire [3:0] reschain;
+
+ FDPE fdres0( .Q(reschain[0]), .C(clk), .CE(1'b1), .D(1'b0), .PRE(glbl_reset) );
+ FDPE fdres1( .Q(reschain[1]), .C(clk), .CE(1'b1), .D(reschain[0]), .PRE(glbl_reset) );
+ FDPE fdres2( .Q(reschain[2]), .C(clk), .CE(1'b1), .D(reschain[1]), .PRE(glbl_reset) );
+ FDPE fdres3( .Q(reschain[3]), .C(clk), .CE(1'b1), .D(reschain[2]), .PRE(glbl_reset) );
+
+ assign reset = reschain[3];
+
+endmodule // sync_reset
View
801 kovan1.srcs/sources_1/imports/kovan1/kovan.v
@@ -0,0 +1,801 @@
+////////////////////////////////////////////////
+// Copyright (c) 2012, Andrew "bunnie" Huang
+// (bunnie _aht_ bunniestudios "dote" com)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+////////////////////////////////////////////////
+
+`timescale 1 ns / 1 ps
+
+parameter C3_NUM_DQ_PINS = 16; // External memory data width
+parameter C3_MEM_ADDR_WIDTH = 13; // External memory address width
+parameter C3_MEM_BANKADDR_WIDTH = 3; // External memory bank address width
+
+module kovan (
+ // camera IF
+ output wire [7:0] CAM_D,
+ output wire CAM_HSYNC, // sync
+ output wire CAM_VSYNC, // pix valid / hsync
+ input wire CAM_MCLKO, // pixel master clock
+ input wire CAM_VCLKO, // pixel clock from CPU
+ output wire CAM_PCLKI, // return pixel clock
+
+ // power management
+ input wire CHG_ACP, // reports presence of AC power
+ output wire CHG_SHDN, // pull low to turn board off
+
+ // HDMI
+ input wire CEC,
+ input wire DDC_SDA_LV_N,
+ output wire DDC_SDA_PU,
+ output wire DDC_SDA_PD,
+ input wire DDC_SCL_LV_N,
+ input wire HPD_N,
+ output wire HPD_NOTIFY,
+ output wire HPD_OVERRIDE,
+ output wire VSYNC_STB,
+
+ // HDMI high speed phy lines
+ input wire [3:0] RX0_TMDS_P,
+ input wire [3:0] RX0_TMDS_N,
+ output wire [3:0] TX0_TMDS_P,
+ output wire [3:0] TX0_TMDS_N,
+
+ // i/o controller digital interfaces
+ output wire [1:0] DIG_ADC_CS,
+ output wire DIG_ADC_IN,
+ input wire DIG_ADC_OUT,
+ output wire DIG_ADC_SCLK,
+ output wire DIG_ADC_CLR,
+ output wire DIG_IN,
+ input wire DIG_OUT,
+ output wire DIG_RCLK,
+ output wire DIG_SAMPLE,
+ output wire DIG_SCLK,
+ output wire DIG_SRLOAD,
+
+ // motor direct drive interfaces
+ output wire [3:0] MBOT,
+ output wire [3:0] MTOP,
+ output wire MOT_EN,
+ output wire [3:0] M_SERVO,
+
+ // optional uart to outside world
+ input wire EXT_TO_HOST_UART, // for now we're a fly on the wall
+ input wire HOST_TO_EXT_UART,
+
+ // infrared receiver
+ input wire IR_RX,
+
+ // switch
+ input wire INPUT_SW0,
+
+ // audio pass-through
+ input wire I2SCDCLK0, // master reference clock to audio PLL
+ output wire I2SCDCLK1,
+ output wire I2SCLK0, // return sample clock to CPU
+ input wire I2SCLK1,
+ input wire I2SDI0, // audio data to playback
+ output wire I2SDI1,
+ output wire I2SDO0, // audio data from record
+ input wire I2SDO1,
+ input wire I2SLRCLK0, // left/right clock to codec
+ output wire I2SLRCLK1,
+
+ // LCD output to display
+ output wire [7:3] LCDO_B, // note truncation of blue channel
+ output wire [7:2] LCDO_G,
+ output wire [7:2] LCDO_R,
+ output wire LCDO_DEN,
+ output wire LCDO_DOTCLK,
+ output wire LCDO_HSYNC,
+ output wire LCDO_RESET_N,
+ output wire LCDO_VSYNC,
+
+ // LCD input from CPU
+ input wire [5:0] LCD_B, // note no truncation of data in
+ input wire [5:0] LCD_G,
+ input wire [5:0] LCD_R,
+ input wire LCD_DEN,
+ input wire LCD_HS,
+ input wire [5:0] LCD_SUPP,
+ input wire LCD_VS,
+ output wire LCD_CLK_T, // clock is sourced from the FPGA
+ // for forward compatibility with HDMI-synced streams
+
+ // SSP interface to the CPU
+ output wire FPGA_MISO,
+ input wire FPGA_MOSI,
+ input wire FPGA_SCLK, // this needs to be fixed to 26 MHz
+ input wire FPGA_SYNC,
+
+ // I2C interfaces
+ input wire PWR_SCL, // we listen on this one
+ inout wire PWR_SDA,
+
+ input wire XI2CSCL, // our primary interface
+ inout wire Xi2CSDA,
+
+ // LED
+ output wire FPGA_LED,
+
+ // mcb interface to DDR2
+ inout [C3_NUM_DQ_PINS-1:0] mcb3_dram_dq,
+ output [C3_MEM_ADDR_WIDTH-1:0] mcb3_dram_a,
+ output [C3_MEM_BANKADDR_WIDTH-1:0] mcb3_dram_ba,
+ output mcb3_dram_ras_n,
+ output mcb3_dram_cas_n,
+ output mcb3_dram_we_n,
+ output mcb3_dram_odt,
+ output mcb3_dram_cke,
+ output mcb3_dram_dm,
+ inout mcb3_dram_udqs,
+ inout mcb3_dram_udqs_n,
+ inout mcb3_rzq,
+ inout mcb3_zio,
+ output mcb3_dram_udm,
+ inout mcb3_dram_dqs,
+ inout mcb3_dram_dqs_n,
+ output mcb3_dram_ck,
+ output mcb3_dram_ck_n
+ );
+
+ ///////// clock buffers
+ wire clk26;
+ wire clk26ibuf;
+ wire clk26buf;
+ wire clk26ibuf;
+
+
+ assign clk26 = FPGA_SCLK;
+ IBUFG clk26buf_ibuf(.I(clk26), .O(clk26ibuf));
+ BUFG clk26buf_buf (.I(clk26ibuf), .O(clk26buf));
+
+
+ ////////// reset
+ wire glbl_reset; // to be used sparingly
+
+
+ ////////// loop-throughs
+ // lcd runs at a target of 6.41 MHz (156 ns cycle time)
+ // i.e., 408 x 262 x 60 Hz (408 is total H width, 320 active, etc.)
+ wire qvga_clkgen_locked;
+
+ clk_wiz_v3_2_qvga qvga_clkgen( .CLK_IN1(clk26buf),
+ .CLK_OUT1(clk_qvga),
+ .RESET(glbl_reset),
+ .LOCKED(qvga_clkgen_locked) );
+
+ reg lcd_pipe_b[5:0];
+ reg lcd_pipe_r[5:0];
+ reg lcd_pipe_g[5:0];
+ reg lcd_pipe_den;
+ reg lcd_hsync;
+ reg lcd_vsync;
+ reg lcd_reset_n;
+ wire lcd_reset;
+
+ sync_reset qvga_reset(
+ .clk(clk_qvga),
+ .glbl_reset(glbl_reset),
+ .reset(lcd_reset) );
+ always @(posedge clk_qvga) begin
+ // TODO: assign timing constraints to ensure hold times met for LCD
+ lcd_pipe_b[5:0] <= LCD_B[5:0];
+ lcd_pipe_g[5:0] <= LCD_G[5:0];
+ lcd_pipe_r[5:0] <= LCD_R[5:0];
+ lcd_pipe_den <= LCD_DEN;
+ lcd_pipe_hsync <= LCD_HS;
+ lcd_pipe_vsync <= LCD_VS;
+ lcd_reset_n <= !lcd_reset;
+ end
+
+ assign LCDO_B[7:3] = lcd_pipe_b[5:1];
+ assign LCDO_G[7:2] = lcd_pipe_g[5:0];
+ assign LCDO_R[7:2] = lcd_pipe_r[5:0];
+ assign LCDO_DEN = lcd_pipe_den;
+ assign LCDO_HSYNC = lcd_pipe_hsync;
+ assign LCDO_VSYNC = lcd_pipe_vsync;
+ assign LCDO_RESET_N = lcd_reset_n;
+
+ // low-skew clock mirroring to an output pin requires this hack
+ ODDR2 qvga_clk_to_lcd (.D0(1'b1), .D1(1'b0),
+ .C0(clk_qvga), .C1(!clk_qvga),
+ .Q(LCDO_DOTCLK), .CE(1), .R(0), .S(0) );
+
+ ODDR2 qvga_clk_to_cpu (.D0(1'b1), .D1(1'b0),
+ .C0(clk_qvga), .C1(!clk_qvga),
+ .Q(LCD_CLK_T), .CE(1), .R(0), .S(0) );
+
+
+ // audio pass-through -- unbuffurred, unregistered for now
+ assign I2SCDCLK1 = I2SCDCLK0;
+ assign I2SCLK0 = I2SCLK1;
+ assign I2SDI1 = I2SDI0;
+ assign I2SDO0 = I2SDO1;
+ assign I2SLRCLK1 = I2SLRCLK0;
+
+ // - add I2C unit --> wire up remaining pins to dummy registers
+
+ // - motor control unit
+
+ /////// DDR2 core 128 MB x 16 of memory, 312 MHz (624 Mt/s = 1.2 GiB/s)
+ // generate a 312 MHz clock from the 26 MHz local buffer
+ wire c3_sys_clk;
+ wire c3_clk_locked;
+ clk_ddr2_26m_312m ddr2_clk(
+ .CLK_IN1(clk26buf),
+ .CLK_OUT1(c3_sys_clk),
+ .RESET(glbl_reset),
+ .LOCKED(c3_clk_locked)
+ );
+
+ // instantiate the core
+ wire c3_clk0; // clock to internal fabric
+ wire c3_rst0;
+ wire [31:0] ddr2_read_data;
+ reg [29:0] ddr2_test_addr;
+
+ ddr2_m3_core_v2 ddr2core(
+ // external wires
+ .mcb3_dram_dq(mcb3_dram_dq),
+ .mcb3_dram_a(mcb3_dram_a),
+ .mcb3_dram_ba(mcb3_dram_ba),
+ .mcb3_dram_ras_n(mcb3_dram_ras_n),
+ .mcb3_dram_cas_n(mcb3_dram_cas_n),
+ .mcb3_dram_we_n(mcb3_dram_we_n),
+ .mcb3_dram_odt(mcb3_dram_odt),
+ .mcb3_dram_cke(mcb3_dram_cke),
+ .mcb3_dram_dm(mcb3_dram_dm),
+ .mcb3_dram_udqs(mcb3_dram_udqs),
+ .mcb3_dram_udqs_n(mcb3_dram_udqs_n),
+ .mcb3_rzq(mcb3_rzq),
+ .mcb3_zio(mcb3_zio),
+ .mcb3_dram_udm(mcb3_dram_udm),
+ .mcb3_dram_dqs(mcb3_dram_dqs),
+ .mcb3_dram_dqs_n(mcb3_dram_dqs_n),
+ .mcb3_dram_ck(mcb3_dram_ck),
+ .mcb3_dram_ck_n(mcb3_dram_ck_n),
+
+ // clock and reset
+ .c3_sys_clk(c3_sys_clk),
+ .c3_sys_rst_i(!c3_clk_locked),
+ .c3_calib_done(c3_calib_done),
+ .c3_clk0(c3_clk0),
+ .c3_rst0(c3_rst0),
+
+ // internal interfaces. only two brought out here for testing
+ // port 2 - read-only
+ .c3_p2_cmd_clk(c3_clk0),
+ .c3_p2_cmd_en(1'b1),
+ .c3_p2_cmd_instr(3'b011),
+ .c3_p2_cmd_bl(6'b1),
+ .c3_p2_cmd_byte_addr(ddr2_test_addr),
+ .c3_p2_rd_clk(c3_clk0),
+ .c3_p2_rd_en(ddr2_test_addr[2]),
+ .c3_p2_rd_data(ddr2_read_data),
+
+ // port 3 - write-only
+ .c3_p3_cmd_clk(c3_clk0),
+ .c3_p3_cmd_en(1'b1),
+ .c3_p3_cmd_instr(3'b010),
+ .c3_p3_cmd_bl(6'b1),
+ .c3_p3_cmd_byte_addr(~ddr2_test_addr),
+ .c3_p3_wr_clk(c3_clk0),
+ .c3_p3_wr_en(!ddr2_test_addr[2]),
+ .c3_p3_wr_mask(4'hf),
+ .c3_p3_wr_data(ddr2_test_addr + 32'haa55)
+ );
+
+ always @(posedge c3_clk0) begin
+ ddr2_test_addr <= ddr2_test_addr + 1;
+ end
+
+ assign ddr2_dummy = ^ ddr2_read_data;
+
+
+ //////////////////////////////////////
+ // cheezy low speed clock divider source
+ //////////////////////////////////////
+ reg [22:0] counter;
+
+ always @(posedge clk26buf) begin
+ counter <= counter + 1;
+
+`ifdef HDMI
+ HDCP_AKSV <= Aksv14_write; // retime it into this domain to not screw up timing closure
+`endif
+ end
+
+ ////////////////////////////////
+ // serial number
+ ////////////////////////////////
+ reg clk2M_unbuf;
+ (* clock_signal = "yes" *)
+ (* PERIOD = "period 0.8125 MHz" *)
+ wire clk2M;
+ wire clk1M;
+ reg clk1M_unbuf;
+ always @(posedge clk26buf) begin
+ clk2M_unbuf <= counter[4]; // 0.8MHz clock: device DNA only runs at 2 MHz
+ clk1M_unbuf <= counter[6];
+ end
+
+ BUFG clk2M_buf(.I(clk2M_unbuf), .O(clk2M));
+ BUFG clk1M_buf(.I(clk1M_unbuf), .O(clk1M));
+
+ wire dna_reset;
+ sync_reset dna_reset(
+ .clk(clk_2M),
+ .glbl_reset(glbl_reset),
+ .reset(dna_reset) );
+
+ reg dna_pulse;
+ reg dna_shift;
+ wire dna_bit;
+ DNA_PORT device_dna( .CLK(clk2M), .DIN(1'b0), .DOUT(dna_bit), .READ(dna_pulse), .SHIFT(dna_shift) );
+
+ parameter DNA_INIT = 4'b1 << 0;
+ parameter DNA_PULSE = 4'b1 << 1;
+ parameter DNA_SHIFT = 4'b1 << 2;
+ parameter DNA_DONE = 4'b1 << 3;
+
+ parameter DNA_nSTATES = 4;
+
+ reg [(DNA_nSTATES-1):0] DNA_cstate = {{(DNA_nSTATES-1){1'b0}}, 1'b1};
+ reg [(DNA_nSTATES-1):0] DNA_nstate;
+ reg [5:0] dna_shift_count;
+
+ always @ (posedge clk2M) begin
+ if (dna_reset)
+ DNA_cstate <= DNA_INIT;
+ else
+ DNA_cstate <=#1 DNA_nstate;
+ end
+
+ always @ (*) begin
+ case (DNA_cstate) //synthesis parallel_case full_case
+ DNA_INIT: begin
+ DNA_nstate = DNA_PULSE;
+ end
+ DNA_PULSE: begin
+ DNA_nstate = DNA_SHIFT;
+ end
+ DNA_SHIFT: begin
+ // depending on if MSB or LSB first, want to use 56 or 55
+ // especially if serial #'s are linear-incrementing
+ DNA_nstate = (dna_shift_count[5:0] == 6'd55) ? DNA_DONE : DNA_SHIFT;
+ end
+ DNA_DONE: begin
+ DNA_nstate = DNA_DONE;
+ end
+ endcase // case (DNA_cstate)
+ end
+
+ always @ (posedge clk2M) begin
+ if( dna_reset ) begin
+ dna_shift_count <= 6'h0;
+ dna_data <= 56'h0;
+ dna_pulse <= 1'b0;
+ dna_shift <= 1'b0;
+ end else begin
+ case (DNA_cstate) //synthesis paralell_case full_case
+ DNA_INIT: begin
+ dna_shift_count <= 6'h0;
+ dna_data <= 56'h0;
+ dna_pulse <= 1'b0;
+ dna_shift <= 1'b0;
+ end
+ DNA_PULSE: begin
+ dna_shift_count <= 6'h0;
+ dna_data <= 56'h0;
+ dna_pulse <= 1'b1;
+ dna_shift <= 1'b0;
+ end
+ DNA_SHIFT: begin
+ dna_shift_count <= dna_shift_count + 6'b1;
+ dna_data[55:0] <= {dna_data[54:0],dna_bit};
+ dna_pulse <= 1'b0;
+ dna_shift <= 1'b1;
+ end
+ DNA_DONE: begin
+ dna_shift_count <= dna_shift_count;
+ dna_data[55:0] <= dna_data[55:0];
+ dna_pulse <= 1'b0;
+ dna_shift <= 1'b0;
+ end
+ endcase // case (DNA_cstate)
+ end // else: !if( dna_reset )
+ end // always @ (posedge clk2M or posedge ~rstbtn_n)
+
+ ////////////////////////////////
+ // heartbeat
+ ////////////////////////////////
+ pwm heartbeat(.clk812k(clk1M), .pwmout(blue_led),
+ .bright(12'b0000_1111_1000), .dim(12'b0000_0001_0000) );
+
+`ifdef HDMI
+ assign FPGA_LED = blue_led | HPD_N;
+`else
+ assign FPGA_LED = blue_led;
+`endif
+
+ //// I2C internal control wiring ////
+ /////////////////
+ /// register 0: control snoop state (SNOOP_CTL r/w)
+ // bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0
+ // | MODEBNK | | | HPD_FRC | SQUASH | RD_STB | RD_HDCP
+ //
+ // bit 0 - RD_HDCP. When 1, select readback of the HDCP set; when 0, select EDID set
+ // bit 1 - RD_STB. When high, update the contents of SNOOP_DAT with data at SNOOP_ADR
+ // bit 2 - enable EDID squashing
+ // bit 3 - when high, force HPD to show that nothing is plugged in; low, act as normal
+ // bit 6 - sets the bank to write with register 0x13 (yah yah this is a hack)
+ //
+ /////////////////
+ /// register 1: snoop readback address (SNOOP_ADR r/w)
+ // bits 7:0 are the address to read back from the snoop unit
+ //
+ /////////////////
+ /// register 2: snoop readback data (SNOOP_DAT ro)
+ // bits 7:0 are the data corresponding to the last loaded snoop address as
+ // selected by RD_HDCP bits in SNOOP_CTL when RD_STB was last toggled
+ //
+ // REVISION -- now dynamically relays the value specified by snoop_adr without having
+ // to toggle RD_STB. RD_STB has no effect currently.
+ /////////////////
+ // register 3: Compositing control (COMP_CTL r/w)
+ // bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0
+ // KM_SEM | RST_GNLK| SMRTLCK | RST_PLL | SELF | COMP_ON | KM_RDY | HDCP_ON
+ //
+ // bit 0 - enable HDCP encryption of the composited stream. Enables HDCP encryption
+ // only if the HDCP cipher is used. If the input stream has no HDCP on it
+ // then this bit has no meaning.
+ // bit 1 - indicates that Km is ready and loaded (currently ignored)
+ // bit 2 - enable compositing of incoming data from LCD port to HDMI stream
+ // bit 3 - when set, ignore incoming data and generate sync based on LCD port signals
+ // bit 4 - when set, resets PLLs only on the paths designated by bit3 ("self")
+ // bit 5 - when set, enable "smart locking", i.e., genlock turns off once we're locked
+ // bit 6 - reset the genlock control machine
+ // bit 7 - Km semaphore -- used to indicate to the kernel whether an existing process
+ // is controlling the Km derivation process. This is to resolve the issue where
+ // the HPD will generate two events to cover Km generation in the case that
+ // the final protocol requires a "restart" to get the correct Km value to stick
+ //
+ /////////////////
+
+ /////////////////
+ // registers 4-7: unused
+ //
+
+ /////////////////
+ // register 8-B: read-only debug registers, meaning reserved
+ //
+
+ /////////////////
+ // register C: extended control set (EXT1_CTL r/w)
+ // bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0
+ // ALPH2 | ALPH1 | ALPH0 | ALPHEN | | | CHROMA |
+ //
+ // bit 7-5: alpha value, 3 bits.
+ // bit 4: alpha blending enable
+ // bit 1: when set, turn on chroma keying; otherwise, always blend in
+ //
+ /////////////////
+ // NOTE: these are now hard-wired to 240, 0, 240. These registers will likely be deprecated soon.
+ // register D: chroma R value, 8 bits
+ // register E: chroma G value, 8 bits
+ // register F: chroma B value, 8 bits
+ //
+ /////////////////
+ // register 0x10 is read-only:
+ // bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0
+ // HDCPDET| VSYNCPOL| HSYNCPOL| LOWVOLT | | CEC | LOCKED | BEND
+ // bit 0: chumby_bend pin state (tied off to insure configuratios as an input)
+ // bit 1: indicates that the genlock machine has locked LCD to HDMI streams
+ // bit 2: CEC pin state (tied off to insure configuratios as an input)
+ // bit 4: when high indicates that a low voltage condition was detected; only active during condition
+ // there is also an interrupt to the CPU that fires
+ // bit 5: indicates the polarity of the HSYNC detected on the HDMI stream, 1 = active high
+ // bit 6: indicates the polarity of the VSYNC detected on the HDMI stream, 1 = active high
+ // bit 7: when high, indicates that an HDCP stream is being encrypted. Not active during
+ // horiz and vert sync periods.
+ //
+ /////////////////
+ // register 0x11-12:
+ // lock tolerance, in pixels, in little-endian byte order
+ // This defines the tolerance of the "lock" threshold. This value matters mostly when
+ // "smart locking" is turned on, i.e., when we want to disable genlock once we're within
+ // our locking tolerance window.
+ //
+ /////////////////
+ // register 0x13 is address of modeline RAM to write
+ // 7 is a write strobe (write when high)
+ // 6:0 is the actual modeline address
+ //
+ /////////////////
+ // register 0x14 is the data to write into the modeline RAM
+ // 7:0 is the data
+ //
+ /////////////////
+ // registers 0x15-0x17:
+ // lock target count, in pixels, in little-endian byte order.
+ // Lock target count is the amount of time that the LCD interface should lead the
+ // HDMI inteface for producing data. The amount of time should be large enough to
+ // absorb timing variations in the interrupt latency handling of the PXA168, but
+ // in all cases smaller than 8 lines of video (that's the size of the line buffers).
+ //
+ // The total time should be expressed in units of pixels, not lines.
+ //
+ /////////////////
+ // register 0x18 is read-only:
+ // bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0
+ // RX_VLD | B_RDY | G_RDY | R_RDY | ALGNERR | SYNLCK | TXLCK | RXLCK
+ // bit 0: rx PLL is locked, indicates that a clock is present and cable is plugged in
+ // bit 1: tx PLL is locked. This should generally always be the case.
+ // bit 2: synthesizer DCM is locked. This should generally always be the case.
+ // bit 3: rx alignment error
+ // bit 4: red channel has received a valid pixel
+ // bit 5: green chanel has received a valid pixel
+ // bit 6: blue channel has received a valid pixel
+ // bit 7: all RX chanels are phase aligned and producing valid data
+ //
+ /////////////////
+ // registers 0x19-0x1f: Km
+ // 56-bit value of Km, entered in little-endian order.
+ //
+ /////////////////
+ // All registers after this point are read-only, and byte-order is little-endian
+ /////////////////
+ // register 0x20-21: horizontal active in pixels
+ // register 0x22-23: vertical active in lines
+ // register 0x24-25: horizontal total width in pixels
+ // register 0x26-28: vertical total height in pixels (not lines)
+ // register 0x29: horizontal front porch in pixels
+ // register 0x2a: horizontal back porch in pixels
+ // register 0x2b-2d: vertical front porch in pixels (not lines)
+ // register 0x2e-30: vertical back porch in pixels (not lines)
+ // register 0x31: horizontal sync width in pixels
+ // register 0x32-0x34: vertical sync width in pixels (not lines)
+ // register 0x35-0x37: reference clock count cycles
+ //
+ // register 0x38-0x3e: device ID (7 bytes)
+ //
+ // register 0x3f: version number
+
+
+ //////////// DEPRACATED REGISTERS ////////////// (but not confident they are dead yet)
+ // register D: line empty/full levels
+ // This sets the level at which we declare the line buffers to be "empty" or "full"
+ // This is on a the granularity of a full video line, not at the pixel level. The
+ // pixel-level full/empty is hard-coded by the FIFO primitive.
+ // bit 7 is ignored
+ // bits [6:4] are the full level target: nominally 2
+ // bit 3 is ignored
+ // bits [2:0] are the empty level target: nominally 2
+ //
+ /////////////////
+ // register E: write and read initial levels
+ // This sets the initial state of the write/read pointers, reset on every vsync.
+ // Note that the actual bit vector that keeps track of active lines can be much longer
+ // than 4 bits, but we only get to diddle with the bottom four bits in this implementation.
+ // bits [7:4] are for the write: nominally 1
+ // bits [3:0] are for the read: nominally 2
+ //
+ /////////////////
+ // register F: reserved
+ //
+
+ wire SDA_pd;
+ wire [7:0] reg_addr;
+ wire wr_stb;
+ wire [7:0] reg_data_in;
+ wire [7:0] reg_a2;
+ wire SDA_int;
+ wire [7:0] snoop_ctl;
+ wire [7:0] snoop_rbk_adr;
+ wire [7:0] snoop_rbk_dat;
+
+`ifdef HDMI
+ // this snippet allows us to clean up an ugly special case in the original i2c engine implementation
+ // what we wanted was a holding register. What was originally implemented was adding a mux to
+ // the *entire* register set! So we move the holding register one level up and simplified things.
+ reg [7:0] reg_data_holding;
+ reg wr_stb_d;
+ always @(posedge clk26buf) begin
+ wr_stb_d <= wr_stb;
+ if (wr_stb & !wr_stb_d) begin // only act on the rising pulse of wr_stb
+ reg_data_holding <= reg_data_in;
+ end else begin
+ reg_data_holding <= reg_data_holding;
+ end
+ end
+`endif
+
+ IOBUF #(.DRIVE(8), .SLEW("SLOW")) IOBUF_sda (.IO(SDA), .I(1'b0), .T(!SDA_pd), .O(SDA_int));
+
+ i2c_slave host_i2c(
+ .SCL(SCL),
+ .SDA(SDA_int),
+ .SDA_pd(SDA_pd),
+
+ .clk(clk26buf),
+ .glbl_reset(glbl_reset),
+
+ .i2c_device_addr(8'h3C),
+`ifdef HDMI
+ .wr_stb(wr_stb),
+ .reg_0(snoop_ctl),
+ .reg_1(snoop_rbk_adr),
+ .reg_2(reg_data_holding),
+ .reg_3(comp_ctl),
+`endif
+
+ .reg_8(8'h34), // reg8-b are placeholders
+ .reg_9(8'h0D),
+ .reg_a(8'hBA),
+ .reg_b(8'hBE),
+
+`ifdef HDMI
+ .reg_c(ext1_ctl),
+
+ // hard-wired to 240, 0, 240
+ // reg_d-f were chroma, now hard-wired to 240, 0, 240
+
+ .reg_10({hdcp_requested,hdmi_vsync_pol,hdmi_hsync_pol,LOWVOLT_NOTIFY,1'b0,CEC,
+ genlock_locked, CHUMBY_BEND}),
+
+
+ .reg_11(lock_tolerance[7:0]),
+ .reg_12(lock_tolerance[15:8]),
+
+ .reg_13({modeline_write,modeline_adr[6:0]}),
+ .reg_14(modeline_dat),
+
+ .reg_15(target_lead_pixels[7:0]),
+ .reg_16(target_lead_pixels[15:8]),
+ .reg_17(target_lead_pixels[23:16]),
+
+ .reg_18({rx_all_valid,
+ rx0_blue_rdy, rx0_green_rdy, rx0_red_rdy,
+ rx0_psalgnerr,
+ m720p_locked, tx0_plllckd, rx0_plllckd}),
+
+ .reg_19(Km[7:0]),
+ .reg_1a(Km[15:8]),
+ .reg_1b(Km[23:16]),
+ .reg_1c(Km[31:24]),
+ .reg_1d(Km[39:32]),
+ .reg_1e(Km[47:40]),
+ .reg_1f(Km[55:48]),
+`endif // `ifdef HDMI
+
+`ifdef HDMI
+ //// read-only registers after this point
+ .reg_20(t_hactive[7:0]),
+ .reg_21({4'b0,t_hactive[11:8]}),
+ .reg_22(t_vactive[7:0]),
+ .reg_23({4'b0,t_vactive[11:8]}),
+ .reg_24(t_htotal[7:0]),
+ .reg_25({4'b0,t_htotal[11:8]}),
+ .reg_26(t_vtotal[7:0]),
+ .reg_27(t_vtotal[15:8]),
+ .reg_28(t_vtotal[23:16]),
+ .reg_29(t_h_fp[7:0]),
+ .reg_2a(t_h_bp[7:0]),
+ .reg_2b(t_v_fp[7:0]),
+ .reg_2c(t_v_fp[15:8]),
+ .reg_2d(t_v_fp[23:16]),
+ .reg_2e(t_v_bp[7:0]),
+ .reg_2f(t_v_bp[15:8]),
+ .reg_30(t_v_bp[23:16]),
+ .reg_31(t_hsync_width[7:0]),
+ .reg_32(t_vsync_width[7:0]),
+ .reg_33(t_vsync_width[15:8]),
+ .reg_34(t_vsync_width[23:16]),
+ .reg_35(t_refclkcnt[7:0]),
+ .reg_36(t_refclkcnt[15:8]),
+ .reg_37(t_refclkcnt[23:16]),
+`endif // `ifdef HDMI
+
+ .reg_38(dna_data[7:0]),
+ .reg_39(dna_data[15:8]),
+ .reg_3a(dna_data[23:16]),
+ .reg_3b(dna_data[31:24]),
+ .reg_3c(dna_data[39:32]),
+ .reg_3d(dna_data[47:40]),
+ .reg_3e(dna_data[55:48]),
+
+ .reg_3f(8'hFF), // version number
+
+ // extended register space:
+ // reg 40 - reg 60 are write registers (32 locations, growable to 64)
+ // reg 80 - reg C0 are read-only registers (64 locations)
+ .reg_40( ), /// control something (written by host)
+ .reg_80( ), /// readback something (read by host)
+
+ /// extened version -- 32 bits to report versions
+ /// kovan starts at FF.000000
+ .reg_fc(8'h0), // this is the LSB of the extended version field
+ .reg_fd(8'h0),
+ .reg_fe(8'h0),
+ .reg_ff(8'h0) // this is the MSB of the extended version field
+ );
+
+ /////// version 4 changes
+ // - added input registers to LCD path to clean up timing
+ // - added a pipeline stage to the core video processing pipe
+ // - adjusted the position of chroma decision versus chroma to remove right pink stripe
+ // - fixed chroma to 240, 0, 240 to reduce computational complexity
+ // - fixed timing files to get better coverage of the FPGA
+ // - inverted clock to device DNA state machine to fix hold time race condition
+ // - self-timed mode is now native, no need to switch FPGA configs
+ // - added PLL and alignment/valid feedback registers to detect when source is present
+ // - touch-up clock tree to improve clarity of timing definition & rule propagation
+ // - full switch-over to PlanAhead tool for compilation
+
+ /////// version 5 changes (log created 8/11/2011)
+ // - changed blue LED from flashing to breathing
+
+ /////// version 6 changes (log created 8/12/2011)
+ // - added off state to LED which is automatically triggered when output not plugged in
+
+ /////// version 7 changes (log created 8/12/2011)
+ // - added SOURCE_NOTIFY reporting trigger
+ // - removed HPD debounce circuit, so HPD reports even when no source is present
+
+ /////// version 8 changes (log cerated 8/21/2011)
+ // - changed timing detector to always report the timing of the Rx stream, even in self-timed mode
+
+ /////// version 9 changes (log created 8/22/2011)
+ // - removed setbox functionality. Box is always "full screen".
+ // Registers 4-B are now deprecated (they are NOPs if written in this implementation, may
+ // change to be active later).
+
+ /////// version A changes (log created 8/22/2011)
+ // - HDCP cipher now resets properly when Ksv is double-initialized
+ // - EDID snooper for HDCP now limits read bounds to 5 to compensate
+ // for tivo series 3 weirdness.
+
+ /////// version B changes (log created 8/27/2011)
+ // - timing closure only
+
+ /////// version C changes (log created 8/27/2011)
+ // - fix chroma issue in overlay mode, was checking too many bits, causing jagged edges on photos
+
+ /////// version D changes (log created 9/5/2011)
+ // - add workaround for Apple TV 2 EESS bug. ATV2 asserts EESS by far too early. Added a trap to catch
+ // EESS when it is asserted too early relative to vsync
+
+ /////// version E changes (log created 9/29/2011)
+ // - fix RGB color depth issue; turns out that extending the LSB's isn't the right way to do it.
+ // now, we truncate the unused bits to zero
+
+ /////// version FF.00000000 changes (log create 2/18/2012)
+ // - branch to kovan
+ // - FF means to check auxiliary vesion field
+
+
+endmodule // kovan
View
266 kovan1.srcs/sources_1/ip/clk_wiz_v3_2_0/clk_ddr2_26m_312m.xco
@@ -0,0 +1,266 @@
+##############################################################
+#
+# Xilinx Core Generator version 13.3
+# Date: Fri Feb 17 09:50:12 2012
+#
+##############################################################
+#
+# This file contains the customisation parameters for a
+# Xilinx CORE Generator IP GUI. It is strongly recommended
+# that you do not manually alter this file as it may cause
+# unexpected and unsupported behavior.
+#
+##############################################################
+#
+# Generated from component: xilinx.com:ip:clk_wiz:3.2
+#
+##############################################################
+#
+# BEGIN Project Options
+SET addpads = false
+SET asysymbol = true
+SET busformat = BusFormatAngleBracketNotRipped
+SET createndf = false
+SET designentry = Verilog
+SET device = xc6slx45
+SET devicefamily = spartan6
+SET flowvendor = Other
+SET formalverification = false
+SET foundationsym = false
+SET implementationfiletype = Ngc
+SET package = csg324
+SET removerpms = false
+SET simulationfiles = Behavioral
+SET speedgrade = -2
+SET verilogsim = true
+SET vhdlsim = false
+# END Project Options
+# BEGIN Select
+SELECT Clocking_Wizard xilinx.com:ip:clk_wiz:3.2
+# END Select
+# BEGIN Parameters
+CSET calc_done=DONE
+CSET clk_in_sel_port=CLK_IN_SEL
+CSET clk_out1_port=CLK_OUT1
+CSET clk_out1_use_fine_ps_gui=false
+CSET clk_out2_port=CLK_OUT2
+CSET clk_out2_use_fine_ps_gui=false
+CSET clk_out3_port=CLK_OUT3
+CSET clk_out3_use_fine_ps_gui=false
+CSET clk_out4_port=CLK_OUT4
+CSET clk_out4_use_fine_ps_gui=false
+CSET clk_out5_port=CLK_OUT5
+CSET clk_out5_use_fine_ps_gui=false
+CSET clk_out6_port=CLK_OUT6
+CSET clk_out6_use_fine_ps_gui=false
+CSET clk_out7_port=CLK_OUT7
+CSET clk_out7_use_fine_ps_gui=false
+CSET clk_valid_port=CLK_VALID
+CSET clkfb_in_n_port=CLKFB_IN_N
+CSET clkfb_in_p_port=CLKFB_IN_P
+CSET clkfb_in_port=CLKFB_IN