blob: 97bd7a11c73c20e692814f7885962cd493947220 [file] [log] [blame]
Tim Edwards44bab472020-10-04 22:09:54 -04001//-------------------------------------
2// SPI controller for Caravel (PicoSoC)
3//-------------------------------------
4// Written by Tim Edwards
5// efabless, inc. September 27, 2020
6//-------------------------------------
7
8//-----------------------------------------------------------
9// This is a standalone slave SPI for the caravel chip that is
10// intended to be independent of the picosoc and independent
11// of all IP blocks except the power-on-reset. This SPI has
12// register outputs controlling the functions that critically
13// affect operation of the picosoc and so cannot be accessed
14// from the picosoc itself. This includes the PLL enables
15// and trim, and the crystal oscillator enable. It also has
16// a general reset for the picosoc, an IRQ input, a bypass for
17// the entire crystal oscillator and PLL chain, the
18// manufacturer and product IDs and product revision number.
19// To be independent of the 1.8V regulator, the slave SPI is
20// synthesized with the 3V digital library and runs off of
21// the 3V supply.
22//
23// This module is designed to be decoupled from the chip
24// padframe and redirected to the wishbone bus under
25// register control from the management SoC, such that the
26// contents can be accessed from the management core via the
27// SPI master.
28//
29//-----------------------------------------------------------
30
31//------------------------------------------------------------
32// Caravel defined registers:
33// Register 0: SPI status and control (unused & reserved)
34// Register 1 and 2: Manufacturer ID (0x0456) (readonly)
35// Register 3: Product ID (= 2) (readonly)
36// Register 4-7: Mask revision (readonly) --- Externally programmed
37// with via programming. Via programmed with a script to match
38// each customer ID.
39//
40// Register 8: PLL enable (1 bit)
41// Register 9: PLL bypass (1 bit)
42// Register 10: IRQ (1 bit)
43// Register 11: reset (1 bit)
44// Register 12: trap (1 bit) (readonly)
45// Register 13-16: PLL trim (26 bits)
46// Register 17: PLL output select (3 bits)
47// Register 18: PLL divider (5 bits)
48//------------------------------------------------------------
49
50module housekeeping_spi(
51`ifdef LVS
52 vdd, vss,
53`endif
54 RSTB, SCK, SDI, CSB, SDO, sdo_enb,
55 mgmt_sck, mgmt_sdi, mgmt_csb, mgmt_sdo,
56 pll_dco_ena, pll_div, pll_sel,
57 pll_trim, pll_bypass, irq, reset, trap,
58 mask_rev_in, pass_thru_reset,
59 pass_thru_mgmt_sck, pass_thru_mgmt_csb,
60 pass_thru_mgmt_sdi, pass_thru_mgmt_sdo,
61 pass_thru_user_sck, pass_thru_user_csb,
62 pass_thru_user_sdi, pass_thru_user_sdo
63);
64
65`ifdef LVS
66 inout vdd; // 3.3V supply
67 inout vss; // common ground
68`endif
69
70 input RSTB; // from padframe
71
72 input SCK; // from padframe
73 input SDI; // from padframe
74 input CSB; // from padframe
75 output SDO; // to padframe
76 output sdo_enb; // to padframe
77
78 input mgmt_sck; // from management SoC
79 input mgmt_sdi; // from management SoC
80 input mgmt_csb; // from management SoC
81 output mgmt_sdo; // to management SoC
82
83 output pll_dco_ena;
84 output [4:0] pll_div;
85 output [2:0] pll_sel;
86 output [25:0] pll_trim;
87 output pll_bypass;
88 output irq;
89 output reset;
90 input trap;
91 input [31:0] mask_rev_in; // metal programmed; 3.3V domain
92
93 // Pass-through programming mode for management area SPI flash
94 output pass_thru_reset;
95 output pass_thru_mgmt_sck;
96 output pass_thru_mgmt_csb;
97 output pass_thru_mgmt_sdi;
98 input pass_thru_mgmt_sdo;
99
100 // Pass-through programming mode for user area SPI flash
101 output pass_thru_user_sck;
102 output pass_thru_user_csb;
103 output pass_thru_user_sdi;
104 input pass_thru_user_sdo;
105
106 reg [25:0] pll_trim;
107 reg [4:0] pll_div;
108 reg [2:0] pll_sel;
109 reg pll_dco_ena;
110 reg pll_bypass;
111 reg reset_reg;
112 reg irq;
113
114 wire [7:0] odata;
115 wire [7:0] idata;
116 wire [7:0] iaddr;
117
118 wire trap;
119 wire rdstb;
120 wire wrstb;
121 wire pass_thru_mgmt; // Mode detected by spi_slave
122 wire pass_thru_mgmt_delay;
123 wire pass_thru_user; // Mode detected by spi_slave
124 wire pass_thru_user_delay;
125
126 // Connect to management SoC SPI master when mgmt_csb is low
127
128 wire loc_sck;
129 wire loc_csb;
130 wire loc_sdi;
131 wire loc_sdo;
132 wire loc_sdoenb;
133
134 assign loc_csb = (mgmt_csb == 1'b0) ? 1'b0 : CSB;
135 assign loc_sck = (mgmt_csb == 1'b0) ? mgmt_sck : SCK;
136 assign loc_sdi = (mgmt_csb == 1'b0) ? mgmt_sdi : SDI;
137
138 assign mgmt_sdo = (mgmt_csb == 1'b0) ? loc_sdo : 1'b0;
139 assign sdo_enb = (mgmt_csb == 1'b0) ? 1'b1 : loc_sdoenb;
140
141 // Pass-through mode handling
142
143 assign pass_thru_mgmt_csb = ~pass_thru_mgmt_delay;
144 assign pass_thru_mgmt_sck = pass_thru_mgmt ? SCK : 1'b0;
145 assign pass_thru_mgmt_sdi = pass_thru_mgmt ? SDI : 1'b0;
146
147 assign pass_thru_user_csb = ~pass_thru_user_delay;
148 assign pass_thru_user_sck = pass_thru_user ? SCK : 1'b0;
149 assign pass_thru_user_sdi = pass_thru_user ? SDI : 1'b0;
150
151 assign SDO = pass_thru_mgmt ? pass_thru_mgmt_sdo :
152 pass_thru_user ? pass_thru_user_sdo : loc_sdo;
153 assign reset = pass_thru_reset ? 1'b1 : reset_reg;
154
155 // Instantiate the SPI slave module
156
157 housekeeping_spi_slave U1 (
158 .reset(~RSTB),
159 .SCK(loc_sck),
160 .SDI(loc_sdi),
161 .CSB(loc_csb),
162 .SDO(loc_sdo),
163 .sdoenb(loc_sdoenb),
164 .idata(odata),
165 .odata(idata),
166 .oaddr(iaddr),
167 .rdstb(rdstb),
168 .wrstb(wrstb),
169 .pass_thru_mgmt(pass_thru_mgmt),
170 .pass_thru_mgmt_delay(pass_thru_mgmt_delay),
171 .pass_thru_user(pass_thru_user),
172 .pass_thru_user_delay(pass_thru_user_delay),
173 .pass_thru_reset(pass_thru_reset)
174 );
175
176 wire [11:0] mfgr_id;
177 wire [7:0] prod_id;
178 wire [31:0] mask_rev;
179
180 assign mfgr_id = 12'h456; // Hard-coded
181 assign prod_id = 8'h10; // Hard-coded
182 assign mask_rev = mask_rev_in; // Copy in to out.
183
184 // Send register contents to odata on SPI read command
185 // All values are 1-4 bits and no shadow registers are required.
186
187 assign odata =
188 (iaddr == 8'h00) ? 8'h00 : // SPI status (fixed)
189 (iaddr == 8'h01) ? {4'h0, mfgr_id[11:8]} : // Manufacturer ID (fixed)
190 (iaddr == 8'h02) ? mfgr_id[7:0] : // Manufacturer ID (fixed)
191 (iaddr == 8'h03) ? prod_id : // Product ID (fixed)
192 (iaddr == 8'h04) ? mask_rev[31:24] : // Mask rev (metal programmed)
193 (iaddr == 8'h05) ? mask_rev[23:16] : // Mask rev (metal programmed)
194 (iaddr == 8'h06) ? mask_rev[15:8] : // Mask rev (metal programmed)
195 (iaddr == 8'h07) ? mask_rev[7:0] : // Mask rev (metal programmed)
196
197 (iaddr == 8'h08) ? {7'b0000000, pll_dco_ena} :
198 (iaddr == 8'h09) ? {7'b0000000, pll_bypass} :
199 (iaddr == 8'h0a) ? {7'b0000000, irq} :
200 (iaddr == 8'h0b) ? {7'b0000000, reset} :
201 (iaddr == 8'h0c) ? {7'b0000000, trap} :
202 (iaddr == 8'h0d) ? pll_trim[7:0] :
203 (iaddr == 8'h0e) ? pll_trim[15:8] :
204 (iaddr == 8'h0f) ? pll_trim[23:16] :
205 (iaddr == 8'h10) ? {6'b000000, pll_trim[25:24]} :
206 (iaddr == 8'h11) ? {5'b00000, pll_sel} :
207 (iaddr == 8'h12) ? {3'b000, pll_div} :
208 8'h00; // Default
209
210 // Register mapping and I/O to slave module
211
212 always @(posedge SCK or negedge RSTB) begin
213 if (RSTB == 1'b0) begin
214 // Set trim for PLL at (almost) slowest rate (~90MHz). However,
215 // pll_trim[12] must be set to zero for proper startup.
216 pll_trim <= 26'b11111111111110111111111111;
217 pll_sel <= 3'b000;
218 pll_div <= 5'b00100; // Default divide-by-8
219 pll_dco_ena <= 1'b1; // Default free-running PLL
220 pll_bypass <= 1'b1; // NOTE: Default bypass mode (don't use PLL)
221 irq <= 1'b0;
222 reset_reg <= 1'b0;
223 end else if (wrstb == 1'b1) begin
224 case (iaddr)
225 8'h08: begin
226 pll_dco_ena <= idata[0];
227 end
228 8'h09: begin
229 pll_bypass <= idata[0];
230 end
231 8'h0a: begin
232 irq <= idata[0];
233 end
234 8'h0b: begin
235 reset_reg <= idata[0];
236 end
237 // Register 0xc is read-only
238 8'h0d: begin
239 pll_trim[7:0] <= idata;
240 end
241 8'h0e: begin
242 pll_trim[15:8] <= idata;
243 end
244 8'h0f: begin
245 pll_trim[23:16] <= idata;
246 end
247 8'h10: begin
248 pll_trim[25:24] <= idata[1:0];
249 end
250 8'h11: begin
251 pll_sel <= idata[2:0];
252 end
253 8'h12: begin
254 pll_div <= idata[4:0];
255 end
256 endcase // (iaddr)
257 end
258 end
259endmodule // housekeeping_spi
260
261//------------------------------------------------------
262// housekeeping_spi_slave.v
263//------------------------------------------------------
264// General purpose SPI slave module for the Caravel chip
265//------------------------------------------------------
266// Written by Tim Edwards
267// efabless, inc., September 28, 2020
268//------------------------------------------------
269// This file is distributed free and open source
270//------------------------------------------------
271
272// SCK --- Clock input
273// SDI --- Data input
274// SDO --- Data output
275// CSB --- Chip select (sense negative)
276// idata --- Data from chip to transmit out, in 8 bits
277// odata --- Input data to chip, in 8 bits
278// addr --- Decoded address to upstream circuits
279// rdstb --- Read strobe, tells upstream circuit to supply next byte to idata
280// wrstb --- Write strobe, tells upstream circuit to latch odata.
281
282// Data format (general purpose):
283// 8 bit format
284// 1st byte: Command word (see below)
285// 2nd byte: Address word (register 0 to 255)
286// 3rd byte: Data word (value 0 to 255)
287
288// Command format:
289// 00000000 No operation
290// 10000000 Write until CSB raised
291// 01000000 Read until CSB raised
292// 11000000 Simultaneous read/write until CSB raised
293// 11000100 Pass-through read/write to management area flash SPI until CSB raised
294// 11000101 Pass-through read/write to user area flash SPI until CSB raised
295// wrnnn000 Read/write as above, for nnn = 1 to 7 bytes, then terminate
296
297// Lower three bits are reserved for future use.
298// All serial bytes are read and written msb first.
299
300// Fixed control and status registers
301
302// Address 0 is reserved and contains flags for SPI mode. This is
303// currently undefined and is always value 0.
304// Address 1 is reserved and contains manufacturer ID low 8 bits.
305// Address 2 is reserved and contains manufacturer ID high 4 bits.
306// Address 3 is reserved and contains product ID (8 bits).
307// Addresses 4 to 7 are reserved and contain the mask ID (32 bits).
308// Addresses 8 to 255 are available for general purpose use.
309
310`define COMMAND 3'b000
311`define ADDRESS 3'b001
312`define DATA 3'b010
313`define USERPASS 3'b100
314`define MGMTPASS 3'b101
315
316module housekeeping_spi_slave(reset, SCK, SDI, CSB, SDO,
317 sdoenb, idata, odata, oaddr, rdstb, wrstb,
318 pass_thru_mgmt, pass_thru_mgmt_delay,
319 pass_thru_user, pass_thru_user_delay, pass_thru_reset);
320
321 input reset;
322 input SCK;
323 input SDI;
324 input CSB;
325 output SDO;
326 output sdoenb;
327 input [7:0] idata;
328 output [7:0] odata;
329 output [7:0] oaddr;
330 output rdstb;
331 output wrstb;
332 output pass_thru_mgmt;
333 output pass_thru_mgmt_delay;
334 output pass_thru_user;
335 output pass_thru_user_delay;
336 output pass_thru_reset;
337
338 reg [7:0] addr;
339 reg wrstb;
340 reg rdstb;
341 reg sdoenb;
342 reg [2:0] state;
343 reg [2:0] count;
344 reg writemode;
345 reg readmode;
346 reg [2:0] fixed;
347 wire [7:0] odata;
348 reg [6:0] predata;
349 wire [7:0] oaddr;
350 reg [7:0] ldata;
351 reg pass_thru_mgmt;
352 reg pass_thru_mgmt_delay;
353 reg pre_pass_thru_mgmt;
354 reg pass_thru_user;
355 reg pass_thru_user_delay;
356 reg pre_pass_thru_user;
357 wire csb_reset;
358
359 assign odata = {predata, SDI};
360 assign oaddr = (state == `ADDRESS) ? {addr[6:0], SDI} : addr;
361 assign SDO = ldata[7];
362 assign csb_reset = CSB | reset;
363 assign pass_thru_reset = pass_thru_mgmt_delay | pre_pass_thru_mgmt;
364
365 // Readback data is captured on the falling edge of SCK so that
366 // it is guaranteed valid at the next rising edge.
367 always @(negedge SCK or posedge csb_reset) begin
368 if (csb_reset == 1'b1) begin
369 wrstb <= 1'b0;
370 ldata <= 8'b00000000;
371 sdoenb <= 1'b1;
372 end else begin
373
374 // After CSB low, 1st SCK starts command
375
376 if (state == `DATA) begin
377 if (readmode == 1'b1) begin
378 sdoenb <= 1'b0;
379 if (count == 3'b000) begin
380 ldata <= idata;
381 end else begin
382 ldata <= {ldata[6:0], 1'b0}; // Shift out
383 end
384 end else begin
385 sdoenb <= 1'b1;
386 end
387
388 // Apply write strobe on SCK negative edge on the next-to-last
389 // data bit so that it updates data on the rising edge of SCK
390 // on the last data bit.
391
392 if (count == 3'b111) begin
393 if (writemode == 1'b1) begin
394 wrstb <= 1'b1;
395 end
396 end else begin
397 wrstb <= 1'b0;
398 end
399 end else if (state == `MGMTPASS || state == `USERPASS) begin
400 wrstb <= 1'b0;
401 sdoenb <= 1'b0;
402 end else begin
403 wrstb <= 1'b0;
404 sdoenb <= 1'b1;
405 end // ! state `DATA
406 end // ! csb_reset
407 end // always @ ~SCK
408
409 always @(posedge SCK or posedge csb_reset) begin
410 if (csb_reset == 1'b1) begin
411 // Default state on reset
412 addr <= 8'h00;
413 rdstb <= 1'b0;
414 predata <= 7'b0000000;
415 state <= `COMMAND;
416 count <= 3'b000;
417 readmode <= 1'b0;
418 writemode <= 1'b0;
419 fixed <= 3'b000;
420 pass_thru_mgmt <= 1'b0;
421 pass_thru_mgmt_delay <= 1'b0;
422 pre_pass_thru_mgmt <= 1'b0;
423 pass_thru_user = 1'b0;
424 pass_thru_user_delay <= 1'b0;
425 pre_pass_thru_user <= 1'b0;
426 end else begin
427 // After csb_reset low, 1st SCK starts command
428 if (state == `COMMAND) begin
429 rdstb <= 1'b0;
430 count <= count + 1;
431 if (count == 3'b000) begin
432 writemode <= SDI;
433 end else if (count == 3'b001) begin
434 readmode <= SDI;
435 end else if (count < 3'b101) begin
436 fixed <= {fixed[1:0], SDI};
437 end else if (count < 3'b110) begin
438 pass_thru_mgmt_delay <= pre_pass_thru_mgmt;
439 pass_thru_user_delay <= pre_pass_thru_user;
440 end else if (count == 3'b111) begin
441 if (pre_pass_thru_mgmt == 1'b1) begin
442 state <= `MGMTPASS;
443 pre_pass_thru_mgmt <= 1'b0;
444 end else if (pre_pass_thru_user == 1'b1) begin
445 state <= `USERPASS;
446 pre_pass_thru_user <= 1'b0;
447 end else begin
448 state <= `ADDRESS;
449 end
450 end
451 end else if (state == `ADDRESS) begin
452 count <= count + 1;
453 addr <= {addr[6:0], SDI};
454 if (count == 3'b111) begin
455 if (readmode == 1'b1) begin
456 rdstb <= 1'b1;
457 end
458 state <= `DATA;
459 end else begin
460 rdstb <= 1'b0;
461 end
462 end else if (state == `DATA) begin
463 predata <= {predata[6:0], SDI};
464 count <= count + 1;
465 if (count == 3'b111) begin
466 if (fixed == 3'b001) begin
467 state <= `COMMAND;
468 end else if (fixed != 3'b000) begin
469 fixed <= fixed - 1;
470 addr <= addr + 1; // Auto increment address (fixed)
471 end else begin
472 addr <= addr + 1; // Auto increment address (streaming)
473 end
474 end else begin
475 rdstb <= 1'b0;
476 end
477 end // ! state `DATA
478 end // ! csb_reset
479 end // always @ SCK
480
481endmodule // housekeeping_spi_slave