blob: 54643c3772b870e114cc2a9ef9f4cabe71a6437a [file] [log] [blame]
Tim Edwardscd64af52020-08-07 11:11:58 -04001//-------------------------------------
2// SPI controller for striVe (PicoSoC)
3//-------------------------------------
4// Written by Tim Edwards
5// efabless, inc. December 23, 2019
6//-------------------------------------
7
8`include "spi_slave.v"
9
10//-----------------------------------------------------------
11// This is a standalone slave SPI for the striVe chip that is
12// intended to be independent of the picosoc and independent
13// of all IP blocks except the power-on-reset. This SPI has
14// register outputs controlling the functions that critically
15// affect operation of the picosoc and so cannot be accessed
16// from the picosoc itself. This includes the PLL enables
17// and trim, and the crystal oscillator enable. It also has
18// a general reset for the picosoc, an IRQ input, a bypass for
19// the entire crystal oscillator and PLL chain, the
20// manufacturer and product IDs and product revision number.
21// To be independent of the 1.8V regulator, the slave SPI is
22// synthesized with the 3V digital library and runs off of
23// the 3V supply.
24//
25//-----------------------------------------------------------
26
27//------------------------------------------------------------
28// Picochip defined registers:
29// Register 0: SPI status and control (unused & reserved)
30// Register 1h: Mask revision (= 0) (readonly)
31// Register 1l and 2: Manufacturer ID (0x456) (readonly)
32// Register 3: Product ID (= 2) (readonly)
33//
34// Register 4: SkyWater IP enable and trim (xtal, regulator, PLL) (8 bits)
35// Register 5: PLL bypass (1 bit)
36// Register 6: IRQ (1 bit)
37// Register 7: reset (1 bit)
38// Register 8: trap (1 bit) (readonly)
39//------------------------------------------------------------
40
41module striVe_spi(
42`ifdef LVS
shalanfd13eb52020-08-21 16:48:07 +020043 vdd, vss,
Tim Edwardscd64af52020-08-07 11:11:58 -040044`endif
shalanfd13eb52020-08-21 16:48:07 +020045 RSTB, SCK, SDI, CSB, SDO, sdo_enb,
46 xtal_ena, reg_ena, pll_dco_ena, pll_div, pll_sel,
47 pll_trim, pll_bypass, irq, reset, RST, trap,
48 mfgr_id, prod_id, mask_rev_in, mask_rev);
Tim Edwardscd64af52020-08-07 11:11:58 -040049
50`ifdef LVS
51 inout vdd; // 3.3V supply
52 inout vss; // common ground
53`endif
54
55 input RSTB; // 3.3V domain
56 input SCK; // 3.3V domain
57 input SDI; // 3.3V domain
58 input CSB; // 3.3V domain
59 output SDO; // 3.3V domain
60 output sdo_enb;
61 output xtal_ena;
62 output reg_ena;
63 output pll_dco_ena;
64 output [25:0] pll_trim;
65 output [2:0] pll_sel;
66 output [4:0] pll_div;
67 output pll_bypass;
68 output irq;
69 output reset;
70 output RST;
71 input trap;
72 input [3:0] mask_rev_in; // metal programmed; 3.3V domain
73 output [11:0] mfgr_id;
74 output [7:0] prod_id;
75 output [3:0] mask_rev;
76
77 reg xtal_ena;
78 reg reg_ena;
79 reg [25:0] pll_trim;
80 reg [4:0] pll_div;
81 reg [2:0] pll_sel;
82 reg pll_dco_ena;
83 reg pll_bypass;
84 reg irq;
85 reg reset;
86
87 wire [7:0] odata;
88 wire [7:0] idata;
89 wire [7:0] iaddr;
90
91 wire trap;
92 wire rdstb;
93 wire wrstb;
94
95 assign RST = ~RSTB;
96
97 // Instantiate the SPI slave module
98
99 spi_slave U1 (
shalanfd13eb52020-08-21 16:48:07 +0200100 .SCK(SCK),
101 .SDI(SDI),
102 .CSB(CSB),
103 .SDO(SDO),
104 .sdoenb(sdo_enb),
105 .idata(odata),
106 .odata(idata),
107 .oaddr(iaddr),
108 .rdstb(rdstb),
109 .wrstb(wrstb)
Tim Edwardscd64af52020-08-07 11:11:58 -0400110 );
111
112 wire [11:0] mfgr_id;
113 wire [7:0] prod_id;
114 wire [3:0] mask_rev;
115
116 assign mfgr_id = 12'h456; // Hard-coded
117 assign prod_id = 8'h05; // Hard-coded
118 assign mask_rev = mask_rev_in; // Copy in to out.
119
120 // Send register contents to odata on SPI read command
121 // All values are 1-4 bits and no shadow registers are required.
122
123 assign odata =
shalanfd13eb52020-08-21 16:48:07 +0200124 (iaddr == 8'h00) ? 8'h00 : // SPI status (fixed)
125 (iaddr == 8'h01) ? {mask_rev, mfgr_id[11:8]} : // Mask rev (metal programmed)
126 (iaddr == 8'h02) ? mfgr_id[7:0] : // Manufacturer ID (fixed)
127 (iaddr == 8'h03) ? prod_id : // Product ID (fixed)
128 (iaddr == 8'h04) ? {5'b00000, xtal_ena, reg_ena, pll_dco_ena} :
129 (iaddr == 8'h05) ? {7'b0000000, pll_bypass} :
130 (iaddr == 8'h06) ? {7'b0000000, irq} :
131 (iaddr == 8'h07) ? {7'b0000000, reset} :
132 (iaddr == 8'h08) ? {7'b0000000, trap} :
133 (iaddr == 8'h09) ? pll_trim[7:0] :
134 (iaddr == 8'h0a) ? pll_trim[15:8] :
135 (iaddr == 8'h0b) ? pll_trim[23:16] :
136 (iaddr == 8'h0c) ? {6'b000000, pll_trim[25:24]} :
137 (iaddr == 8'h0d) ? {5'b00000, pll_sel} :
138 (iaddr == 8'h0e) ? {3'b000, pll_div} :
139 8'h00; // Default
Tim Edwardscd64af52020-08-07 11:11:58 -0400140
141 // Register mapping and I/O to slave module
142
143 always @(posedge SCK or negedge RSTB) begin
shalanfd13eb52020-08-21 16:48:07 +0200144 if (RSTB == 1'b0) begin
145 // Set trim for PLL at (almost) slowest rate (~90MHz). However,
146 // pll_trim[12] must be set to zero for proper startup.
147 pll_trim <= 26'b11111111111110111111111111;
148 pll_sel <= 3'b000;
149 pll_div <= 5'b00100; // Default divide-by-8
150 xtal_ena <= 1'b1;
151 reg_ena <= 1'b1;
152 pll_dco_ena <= 1'b1; // Default free-running PLL
153 pll_bypass <= 1'b1; // NOTE: Default bypass mode (don't use PLL)
154 irq <= 1'b0;
155 reset <= 1'b0;
156 end else if (wrstb == 1'b1) begin
157 case (iaddr)
158 8'h04: begin
159 pll_dco_ena <= idata[2];
160 reg_ena <= idata[1];
161 xtal_ena <= idata[0];
162 end
163 8'h05: begin
164 pll_bypass <= idata[0];
165 end
166 8'h06: begin
167 irq <= idata[0];
168 end
169 8'h07: begin
170 reset <= idata[0];
171 end
172 // Register 8 is read-only
173 8'h09: begin
174 pll_trim[7:0] <= idata;
175 end
176 8'h0a: begin
177 pll_trim[15:8] <= idata;
178 end
179 8'h0b: begin
180 pll_trim[23:16] <= idata;
181 end
182 8'h0c: begin
183 pll_trim[25:24] <= idata[1:0];
184 end
185 8'h0d: begin
186 pll_sel <= idata[2:0];
187 end
188 8'h0e: begin
189 pll_div <= idata[4:0];
190 end
191 endcase // (iaddr)
192 end
Tim Edwardscd64af52020-08-07 11:11:58 -0400193 end
194endmodule // striVe_spi_orig