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 | |
---|
89 | BUFG BUFG_inst ( |
---|
90 | .O(sys_clk50), // Clock buffer output |
---|
91 | .I(osc_clk) // Clock buffer input |
---|
92 | ); |
---|
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 #( |
---|
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) |
---|
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 ( |
---|
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) |
---|
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 |
---|