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;