/ TopGCSPIHostMot2.vhd
TopGCSPIHostMot2.vhd
1 library IEEE; 2 use IEEE.STD_LOGIC_1164.ALL; 3 use IEEE.NUMERIC_STD.ALL; 4 use IEEE.STD_LOGIC_UNSIGNED.ALL; 5 use IEEE.MATH_REAL.ALL; 6 -- 7 -- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics 8 -- http://www.mesanet.com 9 -- 10 -- This program is is licensed under a disjunctive dual license giving you 11 -- the choice of one of the two following sets of free software/open source 12 -- licensing terms: 13 -- 14 -- * GNU General Public License (GPL), version 2.0 or later 15 -- * 3-clause BSD License 16 -- 17 -- 18 -- The GNU GPL License: 19 -- 20 -- This program is free software; you can redistribute it and/or modify 21 -- it under the terms of the GNU General Public License as published by 22 -- the Free Software Foundation; either version 2 of the License, or 23 -- (at your option) any later version. 24 -- 25 -- This program is distributed in the hope that it will be useful, 26 -- but WITHOUT ANY WARRANTY; without even the implied warranty of 27 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 -- GNU General Public License for more details. 29 -- 30 -- You should have received a copy of the GNU General Public License 31 -- along with this program; if not, write to the Free Software 32 -- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 33 -- 34 -- 35 -- The 3-clause BSD License: 36 -- 37 -- Redistribution and use in source and binary forms, with or without 38 -- modification, are permitted provided that the following conditions 39 -- are met: 40 -- 41 -- * Redistributions of source code must retain the above copyright 42 -- notice, this list of conditions and the following disclaimer. 43 -- 44 -- * Redistributions in binary form must reproduce the above 45 -- copyright notice, this list of conditions and the following 46 -- disclaimer in the documentation and/or other materials 47 -- provided with the distribution. 48 -- 49 -- * Neither the name of Mesa Electronics nor the names of its 50 -- contributors may be used to endorse or promote products 51 -- derived from this software without specific prior written 52 -- permission. 53 -- 54 -- 55 -- Disclaimer: 56 -- 57 -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 58 -- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 59 -- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 60 -- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 61 -- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 62 -- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 63 -- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 64 -- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 65 -- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 -- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 67 -- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 68 -- POSSIBILITY OF SUCH DAMAGE. 69 -- 70 Library UNISIM; 71 use UNISIM.vcomponents.all; 72 73 -- dont change these: 74 use work.IDROMConst.all; 75 use work.decodedstrobe.all; 76 -------------------- option selection area ---------------------------- 77 78 79 -------------------- select one card type------------------------------ 80 use work.@Card@.all; 81 82 --use work.i90_x9card.all; -- needs 7i90spi.ucf and SP6 x9 144 pin 83 ----------------------------------------------------------------------- 84 use work.@Pin@.all; 85 --72 pin pinouts for 7I90 86 --use work.PIN_JUSTIO_72.all; 87 --use work.PIN_SVST8_4IM2_72.all; 88 --use work.PIN_SVST8_4_72.all; 89 --use work.PIN_SVST4_8_72.all; 90 --use work.PIN_SVST4_8_ADO_72.all; 91 --use work.PIN_SVST8_8IM2_72.all; 92 --use work.PIN_SVST1_4_7I47S_72.all; 93 --use work.PIN_SVST2_4_7I47_72.all; 94 --use work.PIN_SVST1_5_7I47_72.all; 95 --use work.PIN_2X7I65_72.all; 96 --use work.PIN_ST12_72.all; 97 --use work.PIN_SV12_72.all; 98 --use work.PIN_SVST8_12_2x7I47_72.all; 99 --use work.PIN_SVSP8_6_7I46_72.all; 100 --use work.PIN_24XQCTRONLY_72.all; 101 --use work.PIN_2X7I65_72.all; 102 --use work.PIN_SV12IM_2X7I48_72.all; 103 --use work.PIN_SV6_7I49_72.all; 104 --use work.PIN_SVUA8_4_72.all; 105 --use work.PIN_SVUA8_8_72.all; -- 7I44 pinout UARTS 106 --use work.PIN_DA2_72.all; 107 --use work.PIN_SVST4_8_ADO_72.all; 108 --use work.PIN_SVSS8_8_72.all; 109 --use work.PIN_SSSVST8_8_8_72.all; 110 --use work.PIN_SVSS6_6_72.all; 111 --use work.PIN_SVSSST6_6_12_72.all; 112 --use work.PIN_SVSS6_8_72.all; 113 --use work.PIN_SSSVST8_1_5_7I47_72.all; 114 --use work.PIN_SVSS8_44_72.all; 115 --use work.PIN_RMSVSS6_8_72.all; 116 --use work.PIN_RMSVSS6_12_8_72.all; -- 4i69 5i24 only 117 --use work.PIN_ST8_PLASMA_72.all; 118 --use work.PIN_SV4_7I47S_72.all; 119 --use work.PIN_SVSTUA6_6_6_7I48_72.all; 120 --use work.PIN_SVSTTP6_6_7I39_72.all; 121 --use work.PIN_ST18_72.all; 122 123 ---------------------------------------------------------------------- 124 125 126 -- dont change anything below unless you know what you are doing ----- 127 128 entity TopGCSPIHostMot2 is -- for 7I90 in EPP mode 129 generic 130 ( 131 ThePinDesc: PinDescType := PinDesc; 132 TheModuleID: ModuleIDType := ModuleID; 133 PWMRefWidth: integer := 13; -- PWM resolution is PWMRefWidth-1 bits 134 IDROMType: integer := 3; 135 UseStepGenPrescaler : boolean := true; 136 UseIRQLogic: boolean := true; 137 UseWatchDog: boolean := true; 138 OffsetToModules: integer := 64; 139 OffsetToPinDesc: integer := 448; 140 BusWidth: integer := 32; 141 AddrWidth: integer := 16; 142 InstStride0: integer := 4; -- instance stride 0 = 4 bytes = 1 x 32 bit 143 InstStride1: integer := 64; -- instance stride 1 = 64 bytes = 16 x 32 bit registers 144 RegStride0: integer := 256; -- register stride 0 = 256 bytes = 64 x 32 bit registers 145 RegStride1: integer := 256; -- register stride 1 = 256 bytes - 64 x 32 bit 146 FallBack: boolean := false -- is this a fallback config? 147 148 ); 149 150 Port ( CLK : in std_logic; 151 LEDS : out std_logic_vector(LEDCount -1 downto 0); 152 IOBITS : inout std_logic_vector(IOWidth -1 downto 0); 153 COM_SPICLK : in std_logic; -- host interface SPI ( FPGA is slave) 154 COM_SPIIN : in std_logic; 155 COM_SPIOUT : out std_logic; 156 COM_SPICS : in std_logic; 157 TEST0 : out std_logic; 158 RECONFIG : out std_logic; 159 NINIT : out std_logic; 160 SPICLK : out std_logic; -- config flash spi interface (FPGA is master) 161 SPIIN : in std_logic; 162 SPIOUT : out std_logic; 163 SPICS : out std_logic 164 ); 165 end TopGCSPIHostMot2; 166 167 architecture Behavioral of TopGCSPIHostMot2 is 168 169 constant SPIRead : std_logic_vector(3 downto 0) := x"A"; 170 constant SPIWrite : std_logic_vector(3 downto 0) := x"B"; 171 172 constant SPITimeoutR : real := round(real(ClockLow)*0.000050); -- 50 usec default SPI timeout 173 constant SPITimeout : std_logic_vector(15 downto 0) := std_logic_vector(to_unsigned(integer(SPITimeoutR),16)); 174 signal obus : std_logic_vector(31 downto 0); 175 signal translateaddr : std_logic_vector(AddrWidth-1 downto 0); 176 alias translatestrobe : std_logic is translateaddr(AddrWidth-1); 177 signal loadtranslateram : std_logic; 178 signal readtranslateram : std_logic; 179 signal translateramsel : std_logic; 180 181 signal loadspics : std_logic; 182 signal readspics : std_logic; 183 signal loadspireg : std_logic; 184 signal readspireg : std_logic; 185 186 signal Read32 : std_logic; 187 signal Write32Pipe : std_logic_vector(3 downto 0); 188 alias Write32: std_logic is Write32Pipe(3); 189 190 signal ReconfigSel : std_logic; 191 signal fooidata: std_logic_vector(7 downto 0); 192 193 signal ReConfigreg : std_logic := '0'; 194 signal blinkcount : std_logic_vector(25 downto 0); 195 -- SPI interface signals 196 197 signal SPIRegIn : std_logic_vector(31 downto 0); 198 signal SPIRegOut : std_logic_vector(31 downto 0); 199 signal HM2DataOut : std_logic_vector(31 downto 0); 200 signal HM2DataOutL : std_logic_vector(31 downto 0); 201 signal HM2DataInL : std_logic_vector(31 downto 0); 202 signal AddrPtr : std_logic_vector(15 downto 0); 203 signal SyncAddrPtr : std_logic_vector(15 downto 0); 204 signal SPIBitCount : std_logic_vector(4 downto 0); 205 signal SPIHeader : std_logic; 206 signal DCOM_SPICS : std_logic; 207 signal SPICommand : std_logic_vector(3 downto 0); 208 signal SPIBurstCount : std_logic_vector(6 downto 0); 209 signal SPIAutoInc : std_logic; 210 signal FrameTimer : std_logic_vector(15 downto 0); 211 alias FrameTimerMSB : std_logic is FrameTimer(15); 212 signal FrameTimerMSBD : std_logic; 213 214 signal SPIReadRequest : std_logic; 215 signal SPIReadRequest1 : std_logic; 216 signal SPIReadRequest2 : std_logic; 217 signal SPIWriteRequest : std_logic; 218 signal SPIWriteRequest1 : std_logic; 219 signal SPIWriteRequest2 : std_logic; 220 signal SPIHeaderFlag : std_logic; 221 signal SPIHeaderFlag1 : std_logic; 222 signal SPIHeaderFlag2 : std_logic; 223 signal UpdateSPIReg : std_logic; 224 signal UpdateSPIRegD : std_logic; 225 signal NeedWrite : std_logic; 226 signal fclk : std_logic; 227 228 signal clkfx0: std_logic; 229 signal clk0_0: std_logic; 230 231 signal clklow : std_logic; 232 signal clkfx1: std_logic; 233 signal clk0_1: std_logic; 234 235 236 begin 237 238 ahostmot2: entity work.HostMot2 239 generic map ( 240 thepindesc => ThePinDesc, 241 themoduleid => TheModuleID, 242 idromtype => IDROMType, 243 sepclocks => SepClocks, 244 onews => OneWS, 245 usestepgenprescaler => UseStepGenPrescaler, 246 useirqlogic => UseIRQLogic, 247 pwmrefwidth => PWMRefWidth, 248 usewatchdog => UseWatchDog, 249 offsettomodules => OffsetToModules, 250 offsettopindesc => OffsetToPinDesc, 251 clockhigh => ClockHigh, 252 clockmed => ClockMed, 253 clocklow => ClockLow, 254 boardnamelow => BoardNameLow, 255 boardnamehigh => BoardNameHigh, 256 fpgasize => FPGASize, 257 fpgapins => FPGAPins, 258 ioports => IOPorts, 259 iowidth => IOWidth, 260 liowidth => LIOWidth, 261 portwidth => PortWidth, 262 buswidth => BusWidth, 263 addrwidth => AddrWidth, 264 inststride0 => InstStride0, 265 inststride1 => InstStride1, 266 regstride0 => RegStride0, 267 regstride1 => RegStride1, 268 ledcount => LEDCount ) 269 port map ( 270 ibus => HM2DataInL, 271 obus => HM2DataOut, 272 addr => SyncAddrPtr(AddrWidth-1 downto 2), 273 readstb => read32, 274 writestb => write32, 275 clklow => clklow, -- I/O clock 276 clkmed => clklow, -- Processor clock 277 clkhigh => fclk, -- PWM clock 278 -- int => INT, 279 iobits => IOBITS, 280 leds => LEDS 281 ); 282 283 284 285 286 ClockMultH : DCM 287 generic map ( 288 CLKDV_DIVIDE => 2.0, 289 CLKFX_DIVIDE => 2, 290 CLKFX_MULTIPLY => 8, -- 8 FOR 200 MHz 291 CLKIN_DIVIDE_BY_2 => FALSE, 292 CLKIN_PERIOD => 20.0, 293 CLKOUT_PHASE_SHIFT => "NONE", 294 CLK_FEEDBACK => "1X", 295 DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", 296 297 DFS_FREQUENCY_MODE => "LOW", 298 DLL_FREQUENCY_MODE => "LOW", 299 DUTY_CYCLE_CORRECTION => TRUE, 300 FACTORY_JF => X"C080", 301 PHASE_SHIFT => 0, 302 STARTUP_WAIT => FALSE) 303 port map ( 304 305 CLK0 => clk0_0, -- 306 CLKFB => clk0_0, -- DCM clock feedback 307 CLKFX => clkfx0, 308 CLKIN => CLK, -- Clock input (from IBUFG, BUFG or DCM) 309 PSCLK => '0', -- Dynamic phase adjust clock input 310 PSEN => '0', -- Dynamic phase adjust enable input 311 PSINCDEC => '0', -- Dynamic phase adjust increment/decrement 312 RST => '0' -- DCM asynchronous reset input 313 ); 314 315 BUFG_inst0 : BUFG 316 port map ( 317 O => fclk, -- Clock buffer output 318 I => clkfx0 -- Clock buffer input 319 ); 320 321 ClockMultM : DCM 322 generic map ( 323 CLKDV_DIVIDE => 2.0, 324 CLKFX_DIVIDE => 2, 325 CLKFX_MULTIPLY => 4, -- 4 FOR 100 MHz 326 CLKIN_DIVIDE_BY_2 => FALSE, 327 CLKIN_PERIOD => 20.0, 328 CLKOUT_PHASE_SHIFT => "NONE", 329 CLK_FEEDBACK => "1X", 330 DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", 331 332 DFS_FREQUENCY_MODE => "LOW", 333 DLL_FREQUENCY_MODE => "LOW", 334 DUTY_CYCLE_CORRECTION => TRUE, 335 FACTORY_JF => X"C080", 336 PHASE_SHIFT => 0, 337 STARTUP_WAIT => FALSE) 338 port map ( 339 340 CLK0 => clk0_1, -- 341 CLKFB => clk0_1, -- DCM clock feedback 342 CLKFX => clkfx1, 343 CLKIN => CLK, -- Clock input (from IBUFG, BUFG or DCM) 344 PSCLK => '0', -- Dynamic phase adjust clock input 345 PSEN => '0', -- Dynamic phase adjust enable input 346 PSINCDEC => '0', -- Dynamic phase adjust increment/decrement 347 RST => '0' -- DCM asynchronous reset input 348 ); 349 350 BUFG_inst1 : BUFG 351 port map ( 352 O => clklow, -- Clock buffer output 353 I => clkfx1 -- Clock buffer input 354 ); 355 356 -- End of DCM_inst instantiation 357 358 gcspi: process(clklow,COM_SPICLK) -- SPI interface with separate GClk SPI clock CPOL 0 CPHA 0 359 begin 360 if Rising_edge(COM_SPICLK) then -- sample the SPI data in on rising edge 361 if UpdateSPIReg = '1' then 362 UpdateSPIReg <= '0'; 363 end if; 364 if COM_SPICS= '0' then 365 SPIRegIn <= SPIRegIN(30 downto 0) & COM_SPIIn; -- shift left (MSB first) 366 SPIBitCount <= SPIBitCount +1; 367 if SPIHeader= '1' then 368 if SPIBitCount = "01000" then -- clear command etc at 8 369 AddrPtr <= x"0000"; 370 SPICommand <= "0000"; 371 SPIBurstCount <= "0000000"; 372 SPIAutoInc <= '0'; 373 end if; 374 if SPIBitCount = "10000" then 375 AddrPtr <= SPIRegIn(15 downto 0); -- grab address on the fly at 16 376 end if; 377 if SPIBitCount = "10100" then 378 SPICommand <= SPIRegIn(3 downto 0); -- grab command on the fly at 20 379 end if; 380 if SPIBitCount = "10101" then 381 SPIAutoInc <= SPIRegIn(0); -- grab autoinc on the fly at 21 382 SPIHeaderFlag <= '1'; -- signal HM2 clock domain process 383 end if; 384 if SPIBitCount = "11100" then -- grab burst count at 28 385 SPIBurstCount <= SPIRegIn(6 downto 0); 386 end if; 387 if SPIBitCount = "11111" then 388 SPIHeader <= '0'; 389 end if; 390 else -- not header 391 if SPIBitCount = "11111" then 392 if SPIBurstCount = 1 then 393 SPIHeader <= '1'; 394 else 395 SPIBurstCount <= SPIBurstCount -1; 396 end if; 397 end if; 398 399 end if; --header 400 401 if (SPICommand = SPIRead) and (SPIBitCount = "10110") and (SPIBurstCount /= 1) then -- read request at bit 22 402 SPIReadRequest <= '1'; 403 UpdateSPIReg <= '1'; 404 end if; 405 406 if (SPICommand = SPIWrite) and (SPIBitCount = "10110") and SPIHeader = '0' then -- write request at bit 22 407 NeedWrite <= '1'; 408 end if; 409 410 if NeedWrite = '1' and SPIBitCount = "00000" then 411 SPIWriteRequest <= '1'; 412 HM2DataInL <= SPIRegIn; 413 NeedWrite <= '0'; 414 end if; 415 416 end if; -- CS = 0 417 end if; -- clk falling edge 418 419 if Falling_edge(COM_SPICLK) then -- shift data out on falling edge 420 if COM_SPICS = '0' then 421 if UpDateSPIReg = '1' then 422 UpDateSPIRegD <= '1'; 423 end if; 424 SPIRegOut <= SPIRegOut(30 downto 0) & '0'; 425 if SPIBitCount = "00000" and UpdateSPIRegD = '1' then 426 SPIRegOut <= HM2DataOutL; 427 UpdateSPIRegD <= '0'; 428 end if; 429 end if; 430 end if; 431 432 if rising_edge(ClkLow) then 433 434 SPIReadRequest2 <= SPIReadRequest1; 435 SPIWriteRequest2 <= SPIWriteRequest1; 436 SPIHeaderFlag2 <= SPIHeaderFlag1; 437 438 SPIReadRequest1 <= SPIReadRequest; 439 SPIWriteRequest1 <= SPIWriteRequest; 440 SPIHeaderFlag1 <= SPIHeaderFlag; 441 442 FrameTimerMSBD <= FrameTimerMSB; 443 444 DCOM_SPICS <= COM_SPICS; 445 if DCOM_SPICS = '1' then 446 if FrameTimerMSB = '0' then 447 FrameTimer <= FrameTimer -1; 448 end if; 449 else 450 FrameTimer <= SPITimeout; 451 end if; 452 453 if Read32 = '1' then 454 HM2DataOutL <= HM2DataOut; 455 if SPIAutoInc = '1' then 456 SyncAddrPtr <= SyncAddrPtr +4; 457 end if; 458 end if; 459 460 Write32Pipe <= Write32Pipe(2 downto 0) & (SPIWriteRequest1 and SPIWriteRequest2) ; 461 462 if Write32 = '1' then 463 if SPIAutoInc = '1' then 464 SyncAddrPtr <= SyncAddrPtr +4; 465 end if; 466 end if; 467 468 if (SPIHeaderFlag1 = '1') and (SPIHeaderFlag2 = '1') then 469 SyncAddrPtr <= AddrPtr; 470 end if; 471 472 end if; -- clock low 473 474 if (FrameTimerMSB = '1') and (FrameTimerMSBD = '0') then -- always set header on frame timeout 475 SPIHeader <= '1'; -- async set header 476 SPIRegOut <= x"AAAAAAAA"; 477 end if; 478 479 if (SPIReadRequest1 = '1') and (SPIReadRequest2 = '1') then 480 SPIReadRequest <= '0'; -- async clear request 481 Read32 <= '1'; 482 else 483 Read32 <= '0'; 484 end if; 485 486 487 if (SPIWriteRequest1 = '1') and (SPIWriteRequest2 = '1') then 488 SPIWriteRequest <= '0'; -- async clear request 489 end if; 490 491 if (SPIHeaderFlag1 = '1') and (SPIHeaderFlag2 = '1') then 492 SPIHeaderFlag <= '0'; -- async clear request 493 end if; 494 495 if COM_SPICS = '1' then -- need filter! 496 SPIBitCount <= "00000"; -- async clear bit count 497 end if; 498 499 COM_SPIOUT <= SPIRegOut(31); 500 TEST0 <= SPIReadRequest; 501 end process; 502 503 504 505 ConfigDecode : process(AddrPtr,Read32,Write32) 506 begin 507 LoadSPICS <= decodedstrobe(AddrPtr(AddrWidth-1 downto 2)&"00",x"0070",Write32); 508 ReadSPICS <= decodedstrobe(AddrPtr(AddrWidth-1 downto 2)&"00",x"0070",Read32); 509 LoadSPIReg <= decodedstrobe(AddrPtr(AddrWidth-1 downto 2)&"00",x"0074",Write32); 510 ReadSPIReg <= decodedstrobe(AddrPtr(AddrWidth-1 downto 2)&"00",x"0074",Read32); 511 end process ConfigDecode; 512 513 doreconfig: process (clklow,ReConfigreg, AddrPtr) 514 begin 515 if AddrPtr = x"7F7F" then 516 ReconfigSel <= '1'; 517 else 518 ReconfigSel <= '0'; 519 end if; 520 if rising_edge(clklow) then 521 if Write32 = '1' and ReconfigSel = '1' then 522 if HM2DataInL(7 downto 0) = x"5A" then 523 ReConfigReg <= '1'; 524 end if; 525 end if; 526 end if; 527 RECONFIG <= not ReConfigReg; 528 end process doreconfig; 529 530 asimplspi: entity work.simplespi8 -- configuration serial EEPROM access SPI port 531 generic map 532 ( 533 buswidth => 8, 534 div => 7, -- for divide by 8 -- 12.5 MHz 535 bits => 8 536 ) 537 port map 538 ( 539 clk => clklow, 540 ibus => HM2DataInL(7 downto 0), 541 obus => HM2DataOut(7 Downto 0), 542 loaddata => LoadSPIReg, 543 readdata => ReadSPIReg, 544 loadcs => LoadSPICS, 545 readcs => ReadSPICS, 546 spiclk => SPICLK, 547 spiin => SPIIN, 548 spiout => SPIOUT, 549 spics =>SPICS 550 ); 551 552 dofallback: if fallback generate -- do blinky red light to indicate failure to load primary bitfile 553 Fallbackmode : process(clklow) 554 begin 555 if rising_edge(clklow) then 556 blinkcount <= blinkcount +1; 557 end if; 558 NINIT <= blinkcount(25); 559 end process; 560 end generate; 561 562 donormal: if not fallback generate 563 NormalMode : process(clklow) 564 begin 565 NINIT <= 'Z'; 566 end process; 567 end generate; 568 569 end; 570