1 ------------------------------------------------------------------------
2 -- Copyright 1997-1998 VAutomation Inc. Nashua NH USA.
3 -- Visit HTTP://www.vautomation.com for mor details on our other
4 -- Synthesizable microprocessor and peripheral cores.
5 --
6 -- This program is free software; you can redistribute it and/or modify
7 -- it under the terms of the GNU General Public License version 2 as
8 -- published by the Free Software Foundation.
9 --
10 -- This program is distributed in the hope that it will be useful,
11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 -- GNU General Public License for more details.
14 --
15 -- The GNU Public License can be found at HTTP://www.gnu.org.
16 --
17 -- The copyright notice above MUST remain in the source code at all
18 -- times!
19 --
20 -- File: vspi.vhd
21 -- Revision: $Name: REV9910 $
22 -- Gate Count: 500 gates (LSI Logic 10K)
23 -- Description:
24 --
25 -- Serial Peripheral Interface (SPI)
26 --
27 -- The VSPI core implements an SPI interface compatible with the many
28 -- serial EEPROMs, and microcontrollers. The VSPI core is typically used
29 -- as an SPI master, but it can be configured as an SPI slave as well.
30 --
31 -- The SPI bus is a 3 wire bus that in effect links a serial shift
32 -- register between the "master" and the "slave". Typically both the
33 -- master and slave have an 8 bit shift register so the combined
34 -- register is 16 bits. When an SPI transfer takes place, the master and
35 -- slave shift their shift registers 8 bits and thus exchange their 8
36 -- bit register values.
37 --
38 -- The VPSI core is completely software configurable. The clock
39 -- polarity, clock phase, the clock frequency in master mode, and the
40 -- number of bits to be transferred are all software programmable. These
41 -- configuration bits are usually determined by the capabilities of the
42 -- other device you wish to communicate with.
43 --
44 -- SPI supports multiple slaves on a single 3 wire bus by using seperate
45 -- SLaVe SELect signals (SVLSEL) to enable the desired slave. Multiple
46 -- masters are also supported and some support is provided for detecting
47 -- collisions when multiple masters attempt to transfer at the same
48 -- time.
49 --
50 -- A Wired-OR mode is provided which allows multiple masters to collide
51 -- on the bus without risk of damage. In this mode, an external pullup
52 -- resisitor is required on the SI and SO pins. WOR mode also allows the
53 -- SPI bus to operate as a 2 wire bus by connecting the SI and SO pins
54 -- together to form a single bidirectional data pin.
55 --
56 -- Generally, pullups are recommended on all of the external SPI signals
57 -- to insure they are held in a valid state even when the VSPI core is
58 -- disabled.
59 --
60 -- Limitations:
61
62 -- When operating as a slave, the SPI clock signal (SCK) must be
63 -- slower than 1/8th of the CPU clock. 1/16th is recommended. Note
64 -- that this core is fully synchronous to the cpu CLK and thus SCK
65 -- is sampled and then operated on. This results in 3 to 4 clocks
66 -- of delay which will violate the SPI spec if SCK is faster than
67 -- 1/8th of the CPU clock. When the VSPI core is in master mode, it
68 -- operates exactly on the proper edges since it is generating SCK.
69 --
70 -- The VSPI core was specifically designed to be an SPI master and
71 -- to be connected to a microprocessor such as VAutomations
72 -- V8-uRISC CPU. This core also has the capability to be a slave
73 -- but that feature is considered secondary which is why it is
74 -- speed limited.
75 --
76 -- Register Definition:
77 -- Addr Name R/W Description
78 -- 0 DOUT W 8 Bit data out register
79 -- 0 DIN R 8 Bit data in register
80 -- 1 CTL R/W Control Register
81 -- [0]=Reserved.
82 -- [1]=MSTENB Enable SPI master mode
83 -- [2]=WOR Wire-OR mode enabled
84 -- [3]=CKPOL Clock Polarity 1=SCK idles high,
85 -- 0=SCK idles low
86 -- [4]=PHASE Phase Select
87 -- [6:5]=DVD Clock divide - 00=8, 01=16,
88 -- 10=32, 11=64
89 -- [7]=IRQENB Interrupt enable
90 -- 2 STATUS R/W Interrupt Status register
91 -- Each bit of the status register is cleared to
92 -- zero by by writting ONE to the respective bit.
93 -- [7]=IRQ Interrupt active
94 -- Set at the end of a master mode
95 -- transfer, or when SLVSEL goes high on a
96 -- slave transfer
97 -- [6]=Overrun
98 -- This bit is set when the DOUT register
99 -- is written while an SPI transfer is in
100 -- progress.
101 -- [5]=COL
102 -- This bit is set when there is a master
103 -- mode collision between multiple SPI
104 -- masters. It is set when SLVSEL goes low
105 -- while MSTENB=1.
106 -- [2:4]=zero
107 -- [1]=TXRUN
108 -- 1=Master mode operation underway.
109 -- This bit is read only.
110 -- [0]=SLVSEL
111 -- This bit corresponds to the SLVSEL pin
112 -- on the VSPI core (note that this is
113 -- normally interted at the IO pin). read
114 -- only.
115 -- 3 SSEL R/W Slave Select/bit count register
116 -- SSEL[7:5]
117 -- Number of bits to shift in master mode,
118 -- 000=8 bits, 001=1 bit, 111=7 bits.
119 -- SSEL[4:0]
120 -- 5 individual Slave Selects for master
121 -- mode
122 --
123 -- The VSPI core operates in two fundamentally different modes based on
124 -- the PHASE bit (CTL[4]). The two modes are depicted in the timing
125 -- diagrams below. The key difference centers around the fact that SPI
126 -- data is clocked out on one edge of the clock, and sampled on the
127 -- other. The two modes select where the opposite edge DFF is placed.
128 -- When PHASE=0, a negative edge flop is inserted into the shift_in
129 -- path. The shift_out data is tricky because we must output data from
130 -- the TX_HOLD register for the first bit as we have not seen a clock on
131 -- SCK to clock the data into the shift register. When PHASE=1, the
132 -- negative edge flop is inserted into the shift_out path to hold the
133 -- data for an extra 1/2 clock.
134 --
135 -- Microprocessor interface
136 -- The VSPI microprocessor interface is quite simple and connects
137 -- easily to VAutomations V8-uRISC CPU. Transfers are fully synchronous
138 -- to the CLK signal. When CHIP_SEL and WRITE are both active at the
139 -- rising edge of CLK, a write to the desired register occurs. CHIP_SEL
140 -- and WRITE should only be active for 1 clock cycle.
141 --
142 -- Timing diagram:
143 --
144 -- PHASE=0 (POLCK=0 shown, invert SCKI if POLCK=1)
145 -- Cycle # | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
146 -- _ _ _ _ _ _ _ _
147 -- SCK _______| |_| |_| |_| |_| |_| |_| |_| |_____
148 -- ___ ___ ___ ___ ___ ___ ___ ___
149 -- MOSI ------<_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_>-----
150 -- _____ ___ ___ ___ ___ ___ ___ _______
151 -- MISO ----<___7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_XXXX>-
152 -- _____________________________________
153 -- SLVSEL ___/ \_
154 -- Shift register runs on the second edge of SCKI. A negative edge flop
155 -- is placed in the shift_in path to sample data on the first edge of
156 -- SCKI.
157
158 -- PHASE=1 (POLCK=0 shown, invert SCKI if POLCK=1)
159 -- Cycle # | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
160 -- _ _ _ _ _ _ _ _
161 -- SCK ________| |_| |_| |_| |_| |_| |_| |_| |_______
162 -- ___ ___ ___ ___ ___ ___ ___ ___
163 -- MOSI --------<_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_>-----
164 -- _ ___ ___ ___ ___ ___ ___ _________
165 -- MISO ----XXXXX_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_____>-
166 -- _______________________________________
167 -- SLVSEL ___/ \_
168 -- Shift register runs on the second edge of SCKI. A negative edge flop
169 -- is placed in the shift_out path to hold data data for an extra 1/2
170 -- clock.
171 --
172 -- Crude block diagram:
173 --
174 -- DATAIN--------------------------+
175 -- |
176 -- |\ |
177 -- MISO-------+-------> \ +---v--------+ |\
178 -- | | >-----> 8bit Shift >-------+--------> \
179 -- | +--> / |> Register | | | >-->MOSI
180 -- | | |/ +---v--------+ | +----> /
181 -- | | | | | |/
182 -- | | +---DATAOUT | |
183 -- | | | |
184 -- | +-------------------------+ | |
185 -- | +------------------------|------+ |
186 -- | | |\ | |
187 -- | +--> \ +----+ | |
188 -- | | >------->Neg >-----+----------+
189 -- +--------> / |DFF |
190 -- |/ O|> |
191 -- +----+
192 -- Not shown are the control and status registers, the master mode bit
193 -- counters and other control logic.
194 --
195 -- IO cell Requirements:
196 -- The IO cells required for the SPI bus are quite simple. The following
197 -- VHDL code will synthesize to the appropriate cells.
198 --
199 -- miso = misoo when misoe='1' ELSE 'Z'; -- tristate buffer
200 -- mosi = mosio when mosie='1' ELSE 'Z'; -- tristate buffer
201 -- sck = scko when scke ='1' ELSE 'Z'; -- tristate buffer
202
203 -----------------------------------------------------------------------
204 -- This product is licensed to:
205 -- $name$ of $company$
206 -- for use at site(s):
207 -- $site$
208 --------------Revision History-----------------------------------------
209 -- $Log: vspi.vhd,v $
210 -- Revision 1.7 1999/09/09 16:02:37 scott
211 -- std_ulogic'ified, numeric_std'ified, RMM'ified
212 --
213 -- Revision 1.6 1999/02/17 00:51:50 eric
214 -- Added more checking on various error conditions.
215 --
216 -- Revision 1.5 1999/02/02 19:56:13 eric
217 -- Changes to fully sync to the CPU clock.
218 --
219 -- Revision 1.4 1998/10/16 13:54:57 eric
220 -- Corrected missing sensitiviy list signals for FIRST_BIT.
221 --
222 -- Revision 1.3 1998/09/30 14:56:56 eric
223 -- Initial release level.
224 --
225 -- Revision 1.2 1998/09/24 02:51:44 eric
226 -- Master mode works in phase=0.
227 -----------------------------------------------------------------------
228 --
229 library ieee;
230 use ieee.std_logic_1164.all; -- we use IEEE standard 1164 logic types.
231 --use ieee.numeric_std.all; -- + and - operators
232
233 --use ieee.std_logic_1164.all;
234 use ieee.std_logic_arith.all;
235 use ieee.std_logic_signed.all;
236 use ieee.std_logic_unsigned.all;
237 use ieee.std_ulogic_vector.all;
238
239 entity vspi is ----------------------------ENTITY---------------------
240 port(
241 clk : in std_ulogic; -- everything clocks on rising edge
242 rst : in std_ulogic; -- reset
243 addr : in std_ulogic_vector(1 downto 0); -- address bus
244 datain : in std_ulogic_vector(7 downto 0); -- data bus
245 dataout : out std_ulogic_vector(7 downto 0); -- data bus
246 write : in std_ulogic; -- write enable
247 chip_sel : in std_ulogic; -- device Select
248 irq : out std_ulogic; -- interrupt request
249 -- SPI interface without IO cells
250 misoe : out std_ulogic; -- MISO tristate enable
251 misoi : in std_ulogic; -- Master in/Slave out data in
252 misoo : out std_ulogic; -- MISO data out
253 mosie : out std_ulogic; -- MOSI tristate enable
254 mosii : in std_ulogic; -- Master out/Slave in data in
255 mosio : out std_ulogic; -- MOSI data out
256 scke : out std_ulogic; -- SCK Clock tristate enable
257 scki : in std_ulogic;
258 -- SCK Clock input (shift register runs on this)
259 scko : out std_ulogic; -- SCK clock output
260 slvsele : out std_ulogic; -- tristate enable for slave selects
261 slvselo : out std_ulogic_vector(4 downto 0);
262 -- external slave selects
263 slvsel : in std_ulogic -- Slave Select
264 );
265 end vspi;
266
267 architecture empty of vspi is -------- ARCHITECTURE empty --------
268
269 -- This architecture is provided to easily and quickly remove the SPI
270 -- core for your ASIC or FPGA.
271
272 begin
273 dataout = (others => '0');
274 irq = '0';
275 misoo = '0';
276 misoe = '0';
277 mosie = '0';
278 mosio = '0';
279 scko = '0';
280 scke = '0';
281 slvsele = '0';
282 slvselo = "00000";
283 end empty;
284
285 architecture rtl of vspi is -----------ARCHITECTURE rtl-----------
286 attribute sync_set_reset : string; -- required for synopsys
287 attribute sync_set_reset of rst : signal is "true";
288 -- required for synopsys
289
290 signal bit_ctr : std_ulogic_vector(2 downto 0);
291 -- # bits in a byte
292 signal ctl_reg : std_ulogic_vector(7 downto 0);
293 -- control register
294 signal col_flag : std_ulogic; -- collision flag
295 signal dvd_ctr : std_ulogic_vector(4 downto 0); -- clock divider
296 signal dvd2 : std_ulogic;
297 signal dvd_zero : std_ulogic; -- clk divider controls
298 signal irq_flag : std_ulogic;
299 -- local version of IRQ before gated with IRQENB
300 signal master_mode : std_ulogic; -- Master mode when 1
301 signal misoe_lcl : std_ulogic; -- local version
302 signal mosie_lcl : std_ulogic; -- local version
303 signal oflow : std_ulogic;
304 signal open_drain : std_ulogic;
305 signal phase : std_ulogic;
306 signal polck : std_ulogic;
307 signal sck_r1 : std_ulogic;
308 signal sck_r2 : std_ulogic;
309 signal sck_r3 : std_ulogic; -- synchronizers
310 signal sel_clk : std_ulogic_vector(1 downto 0);
311 signal shift_reg : std_ulogic_vector(7 downto 0);
312 -- THE SPI shift register
313 signal shift_clk : std_ulogic;
314 signal shift_clk_negedge : std_ulogic; -- negative edge of SCK
315 signal shift_negative_edge_nxt : std_ulogic;
316 signal shift_negative_edge : std_ulogic;
317 signal shift_datain : std_ulogic;
318 signal shift_dataout : std_ulogic;
319 signal slvsel_r1 : std_ulogic;
320 signal slvsel_r2 : std_ulogic;
321 signal slvsel_r3 : std_ulogic; -- synchronizers
322 signal spi_go : std_ulogic; -- begin a transfer
323 signal ssel : std_ulogic_vector(7 downto 0);
324 -- slave select register
325 signal status : std_ulogic_vector(7 downto 0);
326 -- status register
327 signal tx_end : std_ulogic;
328 -- TX has completed, TX_RUN will go low
329 signal tx_run : std_ulogic; -- tx is running
330 signal tx_start : std_ulogic;
331 signal tx_start_r1 : std_ulogic;
332
333 begin ---------------------------------------------------------------
334
335 mosio = shift_dataout when mosie_lcl = '1' and open_drain = '0' else
336 '0';
337 mosie = mosie_lcl when open_drain = '0' else
338 '1' when mosie_lcl = '1' and shift_dataout = '0' else
339 -- drive low when open drain enabled.
340 '0';
341
342 misoo = shift_dataout when misoe_lcl = '1' and open_drain = '0' else
343 '0';
344 misoe = misoe_lcl when open_drain = '0' else
345 '1' when misoe_lcl = '1' and shift_dataout = '0' else
346 -- drive low when open drain enabled.
347 '0';
348
349 misoe_lcl = '1' when master_mode = '0' and slvsel = '1' else
350 '0';
351 mosie_lcl = '1' when master_mode = '1' else
352 '0';
353
354 -- spi_go initiates a transfer - A write to the DOUT reg in master
355 -- mode ignore the CPU write if we're already running.
356 spi_go = '1' when chip_sel = '1' and write = '1' and addr = "00" and
357 tx_run = '0' and slvsel_r3 = '0' else
358 '0';
359
360 sr_proc : process(clk) -------------Shift register----------------
361 begin
362 if (clk'event and clk = '1') then
363 if (rst = '1') then
364 shift_reg = "00000000"; -- sync reset
365 else
366 if (spi_go = '1') then -- don't reload while running
367 shift_reg = datain; -- load with data from CPU
368 elsif (shift_clk = '1') then
369 shift_reg = shift_reg(6 downto 0) & shift_datain;
370 end if;
371 end if;
372 end if;
373 end process;
374
375 neg_proc : process(clk) ----------Hold time register--------------
376 begin
377 if (clk'event and clk = '1') then -- negative edge pipeline DFF
378 if (rst = '1') then
379 shift_negative_edge = '0'; -- sync reset
380 elsif (shift_clk_negedge = '1') then
381 shift_negative_edge = shift_negative_edge_nxt;
382 elsif (spi_go = '1') then
383 shift_negative_edge = datain(7); -- preload for phase=0 mode
384 end if;
385 end if;
386 end process;
387
388 shift_negative_edge_nxt = shift_reg(7) when phase = '1' else
389 misoi when master_mode = '1' else
390 mosii;
391
392 shift_dataout = shift_negative_edge when phase = '1' else
393 -- add in the negative edge dff on phase=1
394 shift_reg(7);
395
396 shift_datain = shift_negative_edge when phase = '0' else
397 -- insert the neg DFF in phase=0
398 misoi when master_mode = '1' else
399 mosii;
400
401 tr_proc : process(clk) ---------------TX run------------------
402 -- this bit is active while a transmit is running
403 begin
404 if (clk'event and clk = '1') then
405 if (rst = '1') then
406 tx_run = '0'; -- sync reset
407 else
408 if (tx_start = '1') then
409 tx_run = '1';
410 elsif (tx_end = '1') then
411 tx_run = '0';
412 end if;
413 end if;
414 end if;
415 end process;
416
417 bc_proc : process (clk)
418 begin -------------Bit counter for master mode----------------
419 if (clk'event and clk = '1') then
420 if (rst = '1') then -- sync reset
421 bit_ctr = "000";
422 else
423 if (tx_start = '1') then
424 bit_ctr = ssel(7 downto 5);
425 elsif (shift_clk = '1') then
426 bit_ctr = std_ulogic_vector(unsigned(bit_ctr)-1);
427 end if;
428 end if;
429 end if;
430 end process; -- bit counter
431
432 tx_end = '1' when master_mode = '1' and bit_ctr = "001"
433 and shift_clk = '1' and tx_run = '1' else
434 '0';
435 tx_start = '1' when master_mode = '1' and spi_go = '1' else
436 '0';
437
438 gjr_proc : process (clk)
439 begin ---------Control Register----------------------
440 if (clk'event and clk = '1') then
441 if (rst = '1') then -- sync reset
442 ctl_reg = "00000000";
443 else
444 if (chip_sel = '1' and write = '1' and addr = "01") then -- load
445 ctl_reg = datain;
446 end if;
447 end if;
448 end if;
449 end process;
450
451 -- map the control register to more meaningfull names
452 master_mode = ctl_reg(1);
453 open_drain = ctl_reg(2);
454 polck = ctl_reg(3);
455 phase = ctl_reg(4);
456 sel_clk = ctl_reg(6 downto 5);
457
458 s_proc : process (clk)
459 begin ---------Slave Select Register-------------------------
460 if (clk'event and clk = '1') then
461 if (rst = '1') then -- sync reset
462 ssel = "00000000";
463 else
464 if (chip_sel = '1' and write = '1' and addr = "11") then -- load
465 ssel = datain;
466 end if;
467 end if;
468 end if;
469 end process;
470 slvselo = ssel(4 downto 0); -- drive the port
471 slvsele = master_mode;
472
473 cf_proc : process (clk)
474 begin ---------Collision flag bit---------------------------
475 if (clk'event and clk = '1') then
476 if (rst = '1') then
477 col_flag = '0';
478 else
479 if (master_mode = '1' and slvsel_r3 = '1') then
480 col_flag = '1';
481 elsif (chip_sel = '1' and write = '1'
482 and addr = "10" and datain(5) = '1') then
483 col_flag = '0';
484 end if;
485 end if;
486 end if;
487 end process;
488
489 o_proc : process (clk)
490 begin ---------OFLOw flag bit------------------------------
491 if (clk'event and clk = '1') then
492 if (rst = '1') then
493 oflow = '0';
494 else
495 if (chip_sel = '1' and write = '1' and addr = "00" and
496 -- write to DOUT
497 (tx_run = '1' or slvsel_r3 = '1')) then -- and we're busy
498 oflow = '1';
499 elsif (chip_sel = '1' and write = '1' and addr = "10"
500 and datain(6) = '1') then
501 oflow = '0';
502 end if;
503 end if;
504 end if;
505 end process;
506
507 elr_proc : process (clk)
508 begin ---------IRQ flag bit------------------------------
509 if (clk'event and clk = '1') then
510 if (rst = '1') then
511 irq_flag = '0';
512 else
513 if (tx_end = '1' or (slvsel_r2 = '0' and slvsel_r3 = '1')) then
514 irq_flag = '1';
515 elsif (chip_sel = '1' and write = '1' and addr = "10"
516 and datain(7) = '1') then
517 irq_flag = '0';
518 end if;
519 end if;
520 end if;
521 end process;
522 irq = irq_flag and ctl_reg(7); -- gate with the IRQENB bit.
523
524 flops_proc : process (clk)
525 begin ----------------various pipeline flops---------
526 if (clk'event and clk = '1') then
527 slvsel_r3 = slvsel_r2;
528 slvsel_r2 = slvsel_r1; -- synchronizers
529 slvsel_r1 = slvsel;
530 sck_r3 = sck_r2;
531 sck_r2 = sck_r1; -- synchronizers
532 sck_r1 = not scki xor polck;
533 -- select the desired polarity of the slave clk
534 tx_start_r1 = tx_start;
535 end if;
536 end process;
537
538 dvd_proc : process (clk)
539 begin----------------clock divider for clk generation-------
540 -- create a 2x clock which creates 2 pulses.
541 -- One for each edge of SCK.
542 if (clk'event and clk = '1') then
543 if (not (tx_run = '1' and master_mode = '1') or tx_end = '1') then
544 -- divider only runs when sending data
545 dvd_ctr = "00000";
546 dvd2 = '0';
547 else
548 if (dvd_ctr = "00000") then
549 if (sel_clk = "00") then
550 dvd_ctr = "00011";
551 elsif (sel_clk = "01") then
552 dvd_ctr = "00111";
553 elsif (sel_clk = "10") then
554 dvd_ctr = "01111";
555 else
556 dvd_ctr = "11111";
557 end if;
558 if (tx_start_r1 = '0') then
559 dvd2 = not dvd2;
560 end if;
561 else
562 dvd_ctr = std_ulogic_vector(unsigned(dvd_ctr)-1);
563 end if;
564 end if;
565 end if;
566 end process; -- dvd
567 dvd_zero = '1' when dvd_ctr = "00000" else
568 '0';
569
570 shift_clk = dvd_zero and dvd2 and tx_run and not tx_start_r1
571 -- TX_START_R1 prevents data from shifting on the first
572 -- clock in POLCK=1 mode which we don't want.We only get
573 -- 7 clocks otherwise.
574 when master_mode = '1' else
575 sck_r2 and not sck_r3;
576
577 shift_clk_negedge = dvd_zero and not dvd2 and tx_run
578 when master_mode = '1'
579 else not sck_r2 and sck_r3;
580
581 with addr select
582 dataout = -- dataout multiplexor for register readback
583 shift_reg when "00",
584 ctl_reg when "01",
585 status when "10",
586 ssel when "11",
587 "XXXXXXXX" when others;
588
589 -- assemble the bits that make up the status register
590 status = irq_flag & oflow & col_flag & "000" & tx_run & slvsel_r3;
591
592 scke = master_mode;
593 scko = dvd2 xor polck;
594
595 end rtl;