blob: de6ac2af5ca77e902275f008f3c43fb1de6def22 [file] [log] [blame]
Tim Edwards04ba17f2020-10-02 22:27:50 -04001//----------------------------------------------------------------------------
2// Module: simple_spi_master
3//
4//----------------------------------------------------------------------------
5// Copyright (C) 2019 efabless, inc.
6//
7// This source file may be used and distributed without
8// restriction provided that this copyright statement is not
9// removed from the file and that any derivative work contains
10// the original copyright notice and the associated disclaimer.
11//
12// This source file is free software; you can redistribute it
13// and/or modify it under the terms of the GNU Lesser General
14// Public License as published by the Free Software Foundation;
15// either version 2.1 of the License, or (at your option) any
16// later version.
17//
18// This source is distributed in the hope that it will be
19// useful, but WITHOUT ANY WARRANTY; without even the implied
20// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
21// PURPOSE. See the GNU Lesser General Public License for more
22// details.
23//
24//--------------------------------------------------------------------
25//
26// resetn: active low async reset
27// clk: master clock (before prescaler)
28// stream:
29// 0 = apply/release CSB separately for each byte
30// 1 = apply CSB until stream bit is cleared
31// mlb:
32// 0 = msb 1st
33// 1 = lsb 1st
34// invsck:
35// 0 = normal SCK
36// 1 = inverted SCK
37// invcsb:
38// 0 = normal CSB (active low)
39// 1 = inverted CSB (active high)
40// mode:
41// 0 = read and change data on opposite SCK edges
42// 1 = read and change data on the same SCK edge
43// enable:
44// 0 = disable the SPI master
45// 1 = enable the SPI master
46// irqena:
47// 0 = disable interrupt
48// 1 = enable interrupt
49// prescaler: count (in master clock cycles) of 1/2 SCK cycle.
50//
51// reg_dat_we:
52// 1 = data write enable
53// reg_dat_re:
54// 1 = data read enable
55// reg_cfg_*: Signaling for read/write of configuration register
56// reg_dat_*: Signaling for read/write of data register
57//
58// err_out: Indicates attempt to read/write before data ready
59// (failure to wait for reg_dat_wait to clear)
60//
61// Between "mode" and "invsck", all four standard SPI modes are supported
62//
63//--------------------------------------------------------------------
64
65module simple_spi_master_wb #(
66 parameter BASE_ADR = 32'h2100_0000,
67 parameter CONFIG = 8'h00,
68 parameter DATA = 8'h04
69) (
70 input wb_clk_i,
71 input wb_rst_i,
72 input [31:0] wb_adr_i,
73 input [31:0] wb_dat_i,
74 input [3:0] wb_sel_i,
75 input wb_we_i,
76 input wb_cyc_i,
77 input wb_stb_i,
78 output wb_ack_o,
79 output [31:0] wb_dat_o,
80
81 input sdi, // SPI input
82 output csb, // SPI chip select
83 output sck, // SPI clock
84 output sdo, // SPI output
85 output irq // interrupt output
86);
87
88 wire [31:0] simple_spi_master_reg_cfg_do;
89 wire [31:0] simple_spi_master_reg_dat_do;
90
91 wire resetn = ~wb_rst_i;
92 wire valid = wb_stb_i && wb_cyc_i;
93 wire simple_spi_master_reg_cfg_sel = valid && (wb_adr_i == (BASE_ADR | CONFIG));
94 wire simple_spi_master_reg_dat_sel = valid && (wb_adr_i == (BASE_ADR | DATA));
95
96 wire [1:0] reg_cfg_we = (simple_spi_master_reg_cfg_sel) ?
97 (wb_sel_i[1:0] & {2{wb_we_i}}): 2'b00;
98 wire reg_dat_we = (simple_spi_master_reg_dat_sel) ? (wb_sel_i[0] & wb_we_i): 1'b0;
99
100 wire [31:0] mem_wdata = wb_dat_i;
101 wire reg_dat_re = simple_spi_master_reg_dat_sel && !wb_sel_i && ~wb_we_i;
102
103 assign wb_dat_o = (simple_spi_master_reg_cfg_sel) ? simple_spi_master_reg_cfg_do :
104 simple_spi_master_reg_dat_do;
105 assign wb_ack_o = (simple_spi_master_reg_cfg_sel || simple_spi_master_reg_dat_sel)
106 && (!reg_dat_wait);
107
108 simple_spi_master spi_master (
109 .resetn(resetn),
110 .clk(wb_clk_i),
111 .reg_cfg_we(reg_cfg_we),
112 .reg_cfg_di(mem_wdata),
113 .reg_cfg_do(simple_spi_master_reg_cfg_do),
114 .reg_dat_we(reg_dat_we),
115 .reg_dat_re(reg_dat_re),
116 .reg_dat_di(mem_wdata),
117 .reg_dat_do(simple_spi_master_reg_dat_do),
118 .reg_dat_wait(reg_dat_wait),
119
120 .sdi(sdi), // SPI input
121 .csb(csb), // SPI chip select
122 .sck(sck), // SPI clock
123 .sdo(sdo), // SPI output
124 .irq_out(irq) // interrupt
125 );
126endmodule
127
128module simple_spi_master (
129 input resetn,
130 input clk, // master clock (assume 100MHz)
131
132 input [1:0] reg_cfg_we,
133 input [31:0] reg_cfg_di,
134 output [31:0] reg_cfg_do,
135
136 input reg_dat_we,
137 input reg_dat_re,
138 input [31:0] reg_dat_di,
139 output [31:0] reg_dat_do,
140 output reg_dat_wait,
141 output irq_out,
142 output err_out,
143
144 input sdi, // SPI input
145 output csb, // SPI chip select
146 output sck, // SPI clock
147 output sdo // SPI output
148);
149
150 parameter IDLE = 2'b00;
151 parameter SENDL = 2'b01;
152 parameter SENDH = 2'b10;
153 parameter FINISH = 2'b11;
154
155 reg done;
156 reg isdo, hsck, icsb;
157 reg [1:0] state;
158 reg isck;
159 reg err_out;
160
161 reg [7:0] treg, rreg, d_latched;
162 reg [2:0] nbit;
163
164 reg [7:0] prescaler;
165 reg [7:0] count;
166 reg invsck;
167 reg invcsb;
168 reg mlb;
169 reg irqena;
170 reg stream;
171 reg mode;
172 reg enable;
173
174 wire csb;
175 wire irq_out;
176 wire sck;
177 wire sdo;
178
179 // Define behavior for inverted SCK and inverted CSB
180 assign csb = (invcsb) ? ~icsb : icsb;
181 assign sck = (invsck) ? ~isck : isck;
182
183 // No bidirectional 3-pin mode defined, so SDO is enabled whenever CSB is low.
184 assign sdo = icsb ? 1'bz : isdo;
185
186 assign irq_out = irqena & done;
187
188 // Read configuration and data registers
189 assign reg_cfg_do = {17'd0, irqena, enable, stream, mode, invsck, invcsb, mlb, prescaler};
190 assign reg_dat_wait = ~done;
191 assign reg_dat_do = done ? rreg : ~0;
192
193 // Write configuration register
194 always @(posedge clk or negedge resetn) begin
195 if (resetn == 1'b0) begin
196 prescaler <= 8'd2;
197 invcsb <= 1'b0;
198 invsck <= 1'b0;
199 mlb <= 1'b0;
200 enable <= 1'b0;
201 irqena <= 1'b0;
202 stream <= 1'b0;
203 mode <= 1'b0;
204 end else begin
205 if (reg_cfg_we[0]) prescaler <= reg_cfg_di[7:0];
206 if (reg_cfg_we[1]) begin
207 mlb <= reg_cfg_di[8];
208 invcsb <= reg_cfg_di[9];
209 invsck <= reg_cfg_di[10];
210 mode <= reg_cfg_di[11];
211 stream <= reg_cfg_di[12];
212 enable <= reg_cfg_di[13];
213 irqena <= reg_cfg_di[14];
214 end //reg_cfg_we[1]
215 end //resetn
216 end //always
217
218 // Watch for read and write enables on clk, not hsck, so as not to
219 // miss them.
220
221 reg w_latched, r_latched;
222
223 always @(posedge clk or negedge resetn) begin
224 if (resetn == 1'b0) begin
225 err_out <= 1'b0;
226 w_latched <= 1'b0;
227 r_latched <= 1'b0;
228 d_latched <= 8'd0;
229 end else begin
230 // Clear latches on SEND, otherwise latch when seen
231 if (state == SENDL || state == SENDH) begin
232 if (reg_dat_we == 1'b0) begin
233 w_latched <= 1'b0;
234 end
235 end else begin
236 if (reg_dat_we == 1'b1) begin
237 if (done == 1'b0 && w_latched == 1'b1) begin
238 err_out <= 1'b1;
239 end else begin
240 w_latched <= 1'b1;
241 d_latched <= reg_dat_di[7:0];
242 err_out <= 1'b0;
243 end
244 end
245 end
246
247 if (reg_dat_re == 1'b1) begin
248 if (r_latched == 1'b1) begin
249 r_latched <= 1'b0;
250 end else begin
251 err_out <= 1'b1; // byte not available
252 end
253 end else if (state == FINISH) begin
254 r_latched <= 1'b1;
255 end if (state == SENDL || state == SENDH) begin
256 if (r_latched == 1'b1) begin
257 err_out <= 1'b1; // last byte was never read
258 end else begin
259 r_latched <= 1'b0;
260 end
261 end
262 end
263 end
264
265 // State transition.
266
267 always @(posedge hsck or negedge resetn) begin
268 if (resetn == 1'b0) begin
269 state <= IDLE;
270 nbit <= 3'd0;
271 icsb <= 1'b1;
272 done <= 1'b1;
273 end else begin
274 if (state == IDLE) begin
275 if (w_latched == 1'b1) begin
276 state <= SENDL;
277 nbit <= 3'd0;
278 icsb <= 1'b0;
279 done <= 1'b0;
280 end else begin
281 icsb <= ~stream;
282 end
283 end else if (state == SENDL) begin
284 state <= SENDH;
285 end else if (state == SENDH) begin
286 nbit <= nbit + 1;
287 if (nbit == 3'd7) begin
288 state <= FINISH;
289 end else begin
290 state <= SENDL;
291 end
292 end else if (state == FINISH) begin
293 icsb <= ~stream;
294 done <= 1'b1;
295 state <= IDLE;
296 end
297 end
298 end
299
300 // Set up internal clock. The enable bit gates the internal clock
301 // to shut down the master SPI when disabled.
302
303 always @(posedge clk or negedge resetn) begin
304 if (resetn == 1'b0) begin
305 count <= 8'd0;
306 hsck <= 1'b0;
307 end else begin
308 if (enable == 1'b0) begin
309 count <= 8'd0;
310 end else begin
311 count <= count + 1;
312 if (count == prescaler) begin
313 hsck <= ~hsck;
314 count <= 8'd0;
315 end // count
316 end // enable
317 end // resetn
318 end // always
319
320 // sck is half the rate of hsck
321
322 always @(posedge hsck or negedge resetn) begin
323 if (resetn == 1'b0) begin
324 isck <= 1'b0;
325 end else begin
326 if (state == IDLE || state == FINISH)
327 isck <= 1'b0;
328 else
329 isck <= ~isck;
330 end // resetn
331 end // always
332
333 // Main procedure: read, write, shift data
334
335 always @(posedge hsck or negedge resetn) begin
336 if (resetn == 1'b0) begin
337 rreg <= 8'hff;
338 treg <= 8'hff;
339 isdo <= 1'b0;
340 end else begin
341 if (isck == 1'b0 && (state == SENDL || state == SENDH)) begin
342 if (mlb == 1'b1) begin
343 // LSB first, sdi@msb -> right shift
344 rreg <= {sdi, rreg[7:1]};
345 end else begin
346 // MSB first, sdi@lsb -> left shift
347 rreg <= {rreg[6:0], sdi};
348 end
349 end // read on ~isck
350
351 if (w_latched == 1'b1) begin
352 if (mlb == 1'b1) begin
353 treg <= {1'b1, d_latched[7:1]};
354 isdo <= d_latched[0];
355 end else begin
356 treg <= {d_latched[6:0], 1'b1};
357 isdo <= d_latched[7];
358 end // mlb
359 end else if ((mode ^ isck) == 1'b1) begin
360 if (mlb == 1'b1) begin
361 // LSB first, shift right
362 treg <= {1'b1, treg[7:1]};
363 isdo <= treg[0];
364 end else begin
365 // MSB first shift LEFT
366 treg <= {treg[6:0], 1'b1};
367 isdo <= treg[7];
368 end // mlb
369 end // write on mode ^ isck
370 end // resetn
371 end // always
372
373endmodule