/* File: w3_config_cpld.v This file is Copyright (c) 2012 Mango Communications spi_boot.vhd and its sub-modules Copyright (c) 2005, Arnim Laeuger (arniml@opencores.org) See Readme.txt for details */ module w3_config_cpld( //PLD I/O input osc_clk, input pb, input [3:0] dip_sw, output led_stat, output led_error, //FPGA config pins input fpga_done, input fpga_init, output fpga_prog, output fpga_m0, output fpga_m1, output fpga_m2, //FPGA master SPI flash pins input fpga_spi_mosi, input fpga_spi_fcs, //FPGA serial config pins (shared by slave serial & SPI flash) inout fpga_cclk, output fpga_din, //SD card pins output sd_mosi, input sd_miso, output sd_sclk, output sd_cs_n, input sd_sw_det, input sd_sw_prot, //SPI flash pins input spi_flash_miso, output spi_flash_clk, output spi_flash_cs, output spi_flash_mosi ); wire config_mode_sel; wire sys_reset; wire sd_fpga_cclk, sd_fpga_din, sd_fpga_prog; wire sys_clk, sys_clk50, spi_led_stat, cclk_div; wire pb_debounced; wire done_dly; reg [7:0] pb_d = 8'h00; reg [7:0] sd_det_d = 8'hff; reg [20:0] cclkCounter = 21'b0; reg start_once = 1; wire start_config; wire sd_config_reset; //Use DIP switch to select between SPI Flash and SD Card config modes //config_mode_sel=0 -> SD Card (Slave Serial mode) //config_mode_sel=1 -> SPI Flash (Master SPI mode) assign config_mode_sel = dip_sw[3]; assign sys_reset = dip_sw[0]; //Tie the FPGA config mode pins: // m[2:0] = 001 for master SPI // m[2:0] = 111 for slave serial assign fpga_m2 = ~config_mode_sel; assign fpga_m1 = ~config_mode_sel; assign fpga_m0 = 1; //CRC testing - intentional bit flipping assign fpga_din = config_mode_sel ? spi_flash_miso : sd_fpga_din; assign fpga_cclk = config_mode_sel ? 1'bZ : sd_fpga_cclk; assign fpga_prog = config_mode_sel ? ~pb_debounced : sd_fpga_prog; assign spi_flash_clk = config_mode_sel ? fpga_cclk : 1'b0; assign spi_flash_cs = config_mode_sel ? fpga_spi_fcs : 1'b1; assign spi_flash_mosi = config_mode_sel ? fpga_spi_mosi : 1'b0; BUFG BUFG_inst ( .O(sys_clk50), // Clock buffer output .I(osc_clk) // Clock buffer input ); assign sys_clk = sys_clk50; //Counter to divide down CCLK (for LED blinking) // Current unused, due to resource constraints always @(posedge fpga_cclk) if(fpga_done) cclkCounter <= 0; else cclkCounter <= cclkCounter + 1; assign cclk_div = cclkCounter[20]; //Shift registers for debouncing mechanical switches always @(posedge sys_clk) begin pb_d[7:0] = {pb_d[6:0], pb}; sd_det_d[7:0] = {sd_det_d[6:0], sd_sw_det}; end assign pb_debounced = (pb_d == 8'hff); always @(posedge sys_clk) if(done_dly & start_once) start_once <= 1'b0; else if(~start_once & sd_config_reset) start_once <= 1'b1; assign start_config = (pb_debounced | start_once); //Hold spi_boot core in reset until we're sure SD card has been detected assign sd_config_reset = (sd_det_d != 8'h00); reg [1:0] doneHighCounter = 2'b00; always @(posedge sd_fpga_cclk)// or posedge sys_reset) // if(sys_reset) // doneHighCounter <= 2'b00; if(fpga_done) if(doneHighCounter == 2'b11) doneHighCounter <= doneHighCounter; else doneHighCounter <= doneHighCounter + 1; else doneHighCounter <= 2'b00; assign done_dly = (doneHighCounter == 2'b10); wire [7:0] sd_image_select; assign sd_image_select = {3'b0, dip_sw[2:0]} + 4; spi_boot #( .width_bit_cnt_g(12), // -- 512 bytes per block .width_img_cnt_g(0),// we use one image per set, so the image counter is disabled .num_bits_per_img_g(24), //Big enough for LX130 and LX240 bitstreams (5MB and 9MB, respectively) .sd_init_g(1), // -- use SD specific initialization .mmc_compat_clk_div_g(0), // -- MMC compat 400 kHz > 10 MHz / (13*2) .width_mmc_clk_div_g(0), // -- need 5 bits for MMC compat divider .reset_level_g(1) //Active-high reset ) spi_boot_inst ( .clk_i(sys_clk), .reset_i(sd_config_reset), .set_sel_i(sd_image_select), //std_logic_vector(31-width_img_cnt_g-num_bits_per_img_g downto 0); .spi_clk_o(sd_sclk), .spi_cs_n_o(sd_cs_n), .spi_data_in_i(sd_miso), .spi_data_out_o(sd_mosi), .spi_en_outs_o(), .start_i(start_config), //active high; core datasheet has it backwards .mode_i(1'b1),//1=config mode; core datasheet has it backwards .config_n_o(sd_fpga_prog), .detached_o(detached), .cfg_init_n_i(fpga_init), .cfg_done_i(done_dly), .dat_done_i(done_dly), .cfg_clk_o(sd_fpga_cclk), .cfg_dat_o(sd_fpga_din) ); //Conifg LEDs: STAT (green D17) and ERR (red D18) are active low (0=LED lit) // SPI Flash mode: // STAT: blinks when CCLK is toggling, on solid when DONE is asserted // ERR: on solid if INIT is low while DONE is high (indicating CRC error during config) // SD Card mode: // STAT: on solid when DONE is asserted; blinks when CCLK is toggling and SD card is preset // ERR: on solid if INIT is low while DONE is high (indicating CRC error during config) assign led_stat = config_mode_sel ? ~(fpga_cclk | fpga_done) : ~((fpga_cclk & ~sd_config_reset)| fpga_done); assign led_error = ~(fpga_done & ~fpga_init); endmodule