[1799] | 1 | /* |
---|
| 2 | File: w3_config_cpld.v |
---|
| 3 | |
---|
| 4 | This file is Copyright (c) 2012 Mango Communications |
---|
| 5 | |
---|
| 6 | spi_boot.vhd and its sub-modules Copyright (c) 2005, Arnim Laeuger (arniml@opencores.org) |
---|
| 7 | |
---|
| 8 | See Readme.txt for details |
---|
| 9 | */ |
---|
| 10 | |
---|
| 11 | module w3_config_cpld( |
---|
| 12 | //PLD I/O |
---|
| 13 | input osc_clk, |
---|
| 14 | input pb, |
---|
| 15 | input [3:0] dip_sw, |
---|
| 16 | output led_stat, |
---|
| 17 | output led_error, |
---|
| 18 | |
---|
| 19 | //FPGA config pins |
---|
| 20 | input fpga_done, |
---|
| 21 | input fpga_init, |
---|
| 22 | output fpga_prog, |
---|
| 23 | output fpga_m0, |
---|
| 24 | output fpga_m1, |
---|
| 25 | output fpga_m2, |
---|
| 26 | |
---|
| 27 | //FPGA master SPI flash pins |
---|
| 28 | input fpga_spi_mosi, |
---|
| 29 | input fpga_spi_fcs, |
---|
| 30 | |
---|
| 31 | //FPGA serial config pins (shared by slave serial & SPI flash) |
---|
| 32 | inout fpga_cclk, |
---|
| 33 | output fpga_din, |
---|
| 34 | |
---|
| 35 | //SD card pins |
---|
| 36 | output sd_mosi, |
---|
| 37 | input sd_miso, |
---|
| 38 | output sd_sclk, |
---|
| 39 | output sd_cs_n, |
---|
| 40 | input sd_sw_det, |
---|
| 41 | input sd_sw_prot, |
---|
| 42 | |
---|
| 43 | //SPI flash pins |
---|
| 44 | input spi_flash_miso, |
---|
| 45 | output spi_flash_clk, |
---|
| 46 | output spi_flash_cs, |
---|
| 47 | output spi_flash_mosi |
---|
| 48 | ); |
---|
| 49 | |
---|
| 50 | wire config_mode_sel; |
---|
| 51 | wire sys_reset; |
---|
| 52 | wire sd_fpga_cclk, sd_fpga_din, sd_fpga_prog; |
---|
| 53 | |
---|
| 54 | wire sys_clk, sys_clk50, spi_led_stat, cclk_div; |
---|
| 55 | wire pb_debounced; |
---|
| 56 | wire done_dly; |
---|
| 57 | |
---|
| 58 | reg [7:0] pb_d = 8'h00; |
---|
| 59 | reg [7:0] sd_det_d = 8'hff; |
---|
| 60 | |
---|
| 61 | reg [20:0] cclkCounter = 21'b0; |
---|
| 62 | |
---|
| 63 | reg start_once = 1; |
---|
| 64 | wire start_config; |
---|
| 65 | wire sd_config_reset; |
---|
| 66 | |
---|
| 67 | //Use DIP switch to select between SPI Flash and SD Card config modes |
---|
| 68 | //config_mode_sel=0 -> SD Card (Slave Serial mode) |
---|
| 69 | //config_mode_sel=1 -> SPI Flash (Master SPI mode) |
---|
| 70 | assign config_mode_sel = dip_sw[3]; |
---|
| 71 | assign sys_reset = dip_sw[0]; |
---|
| 72 | |
---|
| 73 | //Tie the FPGA config mode pins: |
---|
| 74 | // m[2:0] = 001 for master SPI |
---|
| 75 | // m[2:0] = 111 for slave serial |
---|
| 76 | assign fpga_m2 = ~config_mode_sel; |
---|
| 77 | assign fpga_m1 = ~config_mode_sel; |
---|
| 78 | assign fpga_m0 = 1; |
---|
| 79 | |
---|
| 80 | //CRC testing - intentional bit flipping |
---|
| 81 | assign fpga_din = config_mode_sel ? spi_flash_miso : sd_fpga_din; |
---|
| 82 | assign fpga_cclk = config_mode_sel ? 1'bZ : sd_fpga_cclk; |
---|
| 83 | assign fpga_prog = config_mode_sel ? ~pb_debounced : sd_fpga_prog; |
---|
| 84 | |
---|
| 85 | assign spi_flash_clk = config_mode_sel ? fpga_cclk : 1'b0; |
---|
| 86 | assign spi_flash_cs = config_mode_sel ? fpga_spi_fcs : 1'b1; |
---|
| 87 | assign spi_flash_mosi = config_mode_sel ? fpga_spi_mosi : 1'b0; |
---|
| 88 | |
---|
[4827] | 89 | BUFG BUFG_inst ( |
---|
| 90 | .O(sys_clk50), // Clock buffer output |
---|
| 91 | .I(osc_clk) // Clock buffer input |
---|
| 92 | ); |
---|
[1799] | 93 | |
---|
| 94 | assign sys_clk = sys_clk50; |
---|
| 95 | |
---|
| 96 | //Counter to divide down CCLK (for LED blinking) |
---|
| 97 | // Current unused, due to resource constraints |
---|
| 98 | always @(posedge fpga_cclk) |
---|
| 99 | if(fpga_done) |
---|
| 100 | cclkCounter <= 0; |
---|
| 101 | else |
---|
| 102 | cclkCounter <= cclkCounter + 1; |
---|
| 103 | |
---|
| 104 | assign cclk_div = cclkCounter[20]; |
---|
| 105 | |
---|
| 106 | //Shift registers for debouncing mechanical switches |
---|
| 107 | always @(posedge sys_clk) |
---|
| 108 | begin |
---|
| 109 | pb_d[7:0] = {pb_d[6:0], pb}; |
---|
| 110 | sd_det_d[7:0] = {sd_det_d[6:0], sd_sw_det}; |
---|
| 111 | end |
---|
| 112 | |
---|
| 113 | assign pb_debounced = (pb_d == 8'hff); |
---|
| 114 | |
---|
| 115 | always @(posedge sys_clk) |
---|
| 116 | if(done_dly & start_once) |
---|
| 117 | start_once <= 1'b0; |
---|
| 118 | else if(~start_once & sd_config_reset) |
---|
| 119 | start_once <= 1'b1; |
---|
| 120 | |
---|
| 121 | assign start_config = (pb_debounced | start_once); |
---|
| 122 | |
---|
| 123 | //Hold spi_boot core in reset until we're sure SD card has been detected |
---|
| 124 | assign sd_config_reset = (sd_det_d != 8'h00); |
---|
| 125 | |
---|
| 126 | reg [1:0] doneHighCounter = 2'b00; |
---|
| 127 | always @(posedge sd_fpga_cclk)// or posedge sys_reset) |
---|
| 128 | // if(sys_reset) |
---|
| 129 | // doneHighCounter <= 2'b00; |
---|
| 130 | if(fpga_done) |
---|
| 131 | if(doneHighCounter == 2'b11) |
---|
| 132 | doneHighCounter <= doneHighCounter; |
---|
| 133 | else |
---|
| 134 | doneHighCounter <= doneHighCounter + 1; |
---|
| 135 | else |
---|
| 136 | doneHighCounter <= 2'b00; |
---|
| 137 | |
---|
| 138 | assign done_dly = (doneHighCounter == 2'b10); |
---|
| 139 | |
---|
| 140 | wire [7:0] sd_image_select; |
---|
| 141 | assign sd_image_select = {3'b0, dip_sw[2:0]} + 4; |
---|
| 142 | |
---|
| 143 | spi_boot #( |
---|
[4827] | 144 | .width_bit_cnt_g(12), // -- 512 bytes per block |
---|
| 145 | .width_img_cnt_g(0),// we use one image per set, so the image counter is disabled |
---|
| 146 | .num_bits_per_img_g(24), //Big enough for LX130 and LX240 bitstreams (5MB and 9MB, respectively) |
---|
| 147 | .sd_init_g(1), // -- use SD specific initialization |
---|
| 148 | .mmc_compat_clk_div_g(0), // -- MMC compat 400 kHz > 10 MHz / (13*2) |
---|
[1799] | 149 | .width_mmc_clk_div_g(0), // -- need 5 bits for MMC compat divider |
---|
| 150 | .reset_level_g(1) //Active-high reset |
---|
| 151 | ) spi_boot_inst ( |
---|
[4827] | 152 | .clk_i(sys_clk), |
---|
| 153 | .reset_i(sd_config_reset), |
---|
| 154 | .set_sel_i(sd_image_select), //std_logic_vector(31-width_img_cnt_g-num_bits_per_img_g downto 0); |
---|
| 155 | .spi_clk_o(sd_sclk), |
---|
| 156 | .spi_cs_n_o(sd_cs_n), |
---|
| 157 | .spi_data_in_i(sd_miso), |
---|
| 158 | .spi_data_out_o(sd_mosi), |
---|
| 159 | .spi_en_outs_o(), |
---|
| 160 | .start_i(start_config), //active high; core datasheet has it backwards |
---|
| 161 | .mode_i(1'b1),//1=config mode; core datasheet has it backwards |
---|
| 162 | .config_n_o(sd_fpga_prog), |
---|
| 163 | .detached_o(detached), |
---|
| 164 | .cfg_init_n_i(fpga_init), |
---|
| 165 | .cfg_done_i(done_dly), |
---|
| 166 | .dat_done_i(done_dly), |
---|
| 167 | .cfg_clk_o(sd_fpga_cclk), |
---|
| 168 | .cfg_dat_o(sd_fpga_din) |
---|
[1799] | 169 | ); |
---|
| 170 | |
---|
| 171 | |
---|
| 172 | //Conifg LEDs: STAT (green D17) and ERR (red D18) are active low (0=LED lit) |
---|
| 173 | // SPI Flash mode: |
---|
| 174 | // STAT: blinks when CCLK is toggling, on solid when DONE is asserted |
---|
| 175 | // ERR: on solid if INIT is low while DONE is high (indicating CRC error during config) |
---|
| 176 | // SD Card mode: |
---|
| 177 | // STAT: on solid when DONE is asserted; blinks when CCLK is toggling and SD card is preset |
---|
| 178 | // ERR: on solid if INIT is low while DONE is high (indicating CRC error during config) |
---|
| 179 | assign led_stat = config_mode_sel ? ~(fpga_cclk | fpga_done) : ~((fpga_cclk & ~sd_config_reset)| fpga_done); |
---|
| 180 | assign led_error = ~(fpga_done & ~fpga_init); |
---|
| 181 | |
---|
| 182 | endmodule |
---|