/ TopSerial16HostMot2.vhd
TopSerial16HostMot2.vhd
   1  library IEEE;
   2  use IEEE.STD_LOGIC_1164.ALL;
   3  use IEEE.STD_LOGIC_ARITH.ALL;
   4  use IEEE.STD_LOGIC_UNSIGNED.ALL;
   5  library UNISIM;
   6  use UNISIM.VComponents.all;
   7  --
   8  -- Copyright (C) 2012, Peter C. Wallace, Mesa Electronics
   9  -- http://www.mesanet.com
  10  --
  11  -- This program is is licensed under a disjunctive dual license giving you
  12  -- the choice of one of the two following sets of free software/open source
  13  -- licensing terms:
  14  --
  15  --    * GNU General Public License (GPL), version 2.0 or later
  16  --    * 3-clause BSD License
  17  -- 
  18  --
  19  -- The GNU GPL License:
  20  -- 
  21  --     This program is free software; you can redistribute it and/or modify
  22  --     it under the terms of the GNU General Public License as published by
  23  --     the Free Software Foundation; either version 2 of the License, or
  24  --     (at your option) any later version.
  25  -- 
  26  --     This program is distributed in the hope that it will be useful,
  27  --     but WITHOUT ANY WARRANTY; without even the implied warranty of
  28  --     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  29  --     GNU General Public License for more details.
  30  -- 
  31  --     You should have received a copy of the GNU General Public License
  32  --     along with this program; if not, write to the Free Software
  33  --     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  34  -- 
  35  -- 
  36  -- The 3-clause BSD License:
  37  -- 
  38  --     Redistribution and use in source and binary forms, with or without
  39  --     modification, are permitted provided that the following conditions
  40  --     are met:
  41  -- 
  42  --         * Redistributions of source code must retain the above copyright
  43  --           notice, this list of conditions and the following disclaimer.
  44  -- 
  45  --         * Redistributions in binary form must reproduce the above
  46  --           copyright notice, this list of conditions and the following
  47  --           disclaimer in the documentation and/or other materials
  48  --           provided with the distribution.
  49  -- 
  50  --         * Neither the name of Mesa Electronics nor the names of its
  51  --           contributors may be used to endorse or promote products
  52  --           derived from this software without specific prior written
  53  --           permission.c1
  54  -- 
  55  -- 
  56  -- Disclaimer:
  57  -- 
  58  --     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  59  --     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  60  --     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  61  --     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  62  --     COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  63  --     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  64  --     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  65  --     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  66  --     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  67  --     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  68  --     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  69  --     POSSIBILITY OF SUCH DAMAGE.
  70  -- 
  71  -- dont change these:
  72  use work.IDROMConst.all;	
  73  
  74  -------------------- option selection area ----------------------------
  75  
  76  
  77  -------------------- select one card type------------------------------
  78  use work.@Card@.all;
  79  --use work.i90_x9card.all; 		-- 
  80  
  81  -----------------------------------------------------------------------
  82  
  83  
  84  -------------------- select (or add) one pinout -----------------------
  85  
  86  use work.@Pin@.all;
  87  
  88  -- 72 pin pinouts for 7I90HD
  89  --use work.PIN_JUSTIO_72.all;
  90  --use work.PIN_SVST8_4IM2_72.all;
  91  --use work.PIN_SVST8_4_72.all;
  92  --use work.PIN_SVST4_8_72.all;
  93  --use work.PIN_SVST4_8_ADO_72.all;
  94  --use work.PIN_SVST8_8IM2_72.all;
  95  --use work.PIN_SVST1_4_7I47S_72.all;
  96  --use work.PIN_SVST2_4_7I47_72.all;
  97  --use work.PIN_SVST1_5_7I47_72.all;
  98  --use work.PIN_2X7I65_72.all;
  99  --use work.PIN_ST12_72.all;
 100  --use work.PIN_SV12_72.all;
 101  --use work.PIN_SVST8_12_2x7I47_72.all;
 102  --use work.PIN_SVSP8_6_7I46_72.all;
 103  --use work.PIN_24XQCTRONLY_72.all;
 104  --use work.PIN_2X7I65_72.all;
 105  --use work.PIN_SV12IM_2X7I48_72.all;
 106  --use work.PIN_SV6_7I49_72.all;
 107  --use work.PIN_SVUA8_4_72.all;
 108  --use work.PIN_SVUA8_8_72.all; -- 7I44 pinout UARTS
 109  --use work.PIN_DA2_72.all;
 110  --use work.PIN_SVST4_8_ADO_72.all;
 111  --use work.PIN_SVSS8_8_72.all;
 112  --use work.PIN_SSSVST8_8_8_72.all;
 113  --use work.PIN_SVSS6_6_72.all;
 114  --use work.PIN_SVSS6_8_72.all;
 115  --use work.PIN_BASACKWARDS_SVSS6_8_72.all;
 116  --use work.PIN_SSSVST8_1_5_7I47_72.all;
 117  --use work.PIN_SVSS8_44_72.all;
 118  --use work.PIN_RMSVSS6_8_72.all;
 119  --use work.PIN_RMSVSS6_12_8_72.all; -- 4i69 5i24 7I80 only
 120  --use work.PIN_ST8_PLASMA_72.all;
 121  --use work.PIN_SV4_7I47S_72.all;
 122  --use work.PIN_SVSTUA6_6_6_7I48_72.all;
 123  --use work.PIN_SVSTTP6_6_7I39_72.all;
 124  --use work.PIN_ST18_72.all;
 125  --use work.PIN_SSSV6_36_72.all;
 126  --use work.PIN_FASSSVRP4_4_4_72.all;
 127  --use work.PIN_FA1_72.all;
 128  --use work.PIN_BI1_72.all;
 129  --use work.PIN_SISS4_4_72.all;
 130  --use work.PIN_SUBSERIAL_BASE_72.all;
 131  --use work.PIN_7I90SPIHost_72.all;
 132  --use work.PIN_SC36_72.all;
 133  
 134  ----------------------------------------------------------------------
 135  	
 136  	
 137  -- dont change anything below unless you know what you are doing -----
 138  	
 139  entity TopSerialHostMot2 is -- for 7I90HD/7I90DB
 140  	 generic 
 141  	 (
 142  		ThePinDesc: PinDescType := PinDesc;
 143  		TheModuleID: ModuleIDType := ModuleID;
 144  		PWMRefWidth: integer := 13;	-- PWM resolution is PWMRefWidth-1 bits 
 145  		IDROMType: integer := 3;		
 146  		UseStepGenPrescaler : boolean := true;
 147  		UseIRQLogic: boolean := true;
 148  		UseWatchDog: boolean := true;
 149  		OffsetToModules: integer := 64;
 150  		OffsetToPinDesc: integer := 448;
 151  		BusWidth: integer := 32;
 152  		AddrWidth: integer := 16;
 153  		InstStride0: integer := 4;			-- instance stride 0 = 4 bytes = 1 x 32 bit
 154  		InstStride1: integer := 64;		-- instance stride 1 = 64 bytes = 16 x 32 bit registers
 155  		RegStride0: integer := 256;		-- register stride 0 = 256 bytes = 64 x 32 bit registers
 156  		RegStride1: integer := 256;      -- register stride 1 = 256 bytes - 64 x 32 bit
 157  		FallBack: boolean := false			-- is this a fallback config?
 158  
 159  		);
 160  						
 161  		
 162  	Port (	CLK : in std_logic;
 163  				LEDS : out std_logic_vector(LEDCount -1 downto 0);
 164  				IOBITS : inout std_logic_vector(IOWidth -1 downto 0);
 165  				SPICLK : out std_logic;
 166  				SPIIN : in std_logic;
 167  				SPIOUT : out std_logic;
 168  				SPICS : out std_logic;
 169  				NINIT : out std_logic;
 170  				RXDATA : in std_logic;
 171  				TXDATA : out std_logic;
 172  				TXEN : out std_logic;
 173  				TP : out std_logic_vector(1 downto 0);
 174  				OPTS : in std_logic_vector(1 downto 0);
 175  				RECONFIG : out std_logic
 176  		 );
 177  end TopSerialHostMot2;
 178  
 179  
 180  architecture Behavioral of TopSerialHostMot2 is
 181  	 
 182  -- GPIO interface signals
 183  
 184  signal LoadSPIReg : std_logic;
 185  signal ReadSPIReg : std_logic;
 186  signal LoadSPICS : std_logic;
 187  signal ReadSPICS : std_logic;
 188  
 189  signal TPReg : std_logic_vector(1 downto 0);
 190  signal SetTPReg0 : std_logic;
 191  signal ClrTPReg0 : std_logic;
 192  signal SetTPReg1 : std_logic;
 193  signal ClrTPReg1 : std_logic;
 194  signal ReadOpts : std_logic;
 195  
 196  signal iabus : std_logic_vector(11 downto 0);	-- program address bus 
 197  signal idbus : std_logic_vector(23 downto 0);	-- program data bus		 
 198  signal mradd : std_logic_vector(11 downto 0);	-- memory read address
 199  signal ioradd :  std_logic_vector(11 downto 0);	-- I/O read address
 200  signal mwadd : std_logic_vector(11 downto 0);	-- memory write address
 201  signal mibus : std_logic_vector(15 downto 0);	-- memory data in bus	  
 202  signal mobus : std_logic_vector(15 downto 0);	-- memory data out bus
 203  signal mwrite : std_logic;								-- memory write signal		  
 204  signal mread : std_logic;								-- memory read signal	
 205  
 206  signal mibus_ram : std_logic_vector(15 downto 0);	-- memory data in bus RAM
 207  signal mibus_io : std_logic_vector(15 downto 0);	-- memory data in bus IO
 208  
 209  signal wiosel : std_logic;
 210  signal riosel : std_logic;
 211  
 212  signal WriteLEDs : std_logic;
 213  signal WriteLEDMode : std_logic;
 214  signal LocalLEDs : std_logic_vector(1 downto 0);	
 215  signal LEDMode: std_logic;
 216  signal LEDErrFF: std_logic;
 217  signal WriteErrLED: std_logic;
 218  
 219  signal ReadExtData : std_logic;
 220  signal WriteExtData : std_logic;
 221  signal ReadExtAdd	 : std_logic;	
 222  signal WriteExtAdd : std_logic;		
 223  signal StartExtRead : std_logic;	
 224  signal StartExtWrite : std_logic;
 225  signal ExtAddrInc	 : std_logic;
 226  signal Rates : std_logic_vector(4 downto 0);
 227  signal ReadRates : std_logic;
 228  signal ReadTimer : std_logic;
 229  signal Timer : std_logic_vector(15 downto 0);
 230  signal PreScale : std_logic_vector(7 downto 0);
 231  signal HM2ReadBuffer: std_logic_vector(31 downto 0);
 232  signal HM2WriteBuffer : std_logic_vector(31 downto 0);
 233  
 234  signal Write32 : std_logic;
 235  signal Read32 : std_logic;
 236  signal Read32d : std_logic;
 237  
 238  -- RX UART signals
 239  signal ReadPktUARTRData : std_logic;
 240  signal ReadPktUARTRFrameCount : std_logic;			
 241  signal LoadPktUARTRBitRateL : std_logic;
 242  signal ReadPktUARTRBitrateL : std_logic;
 243  signal LoadPktUARTRBitRateH : std_logic;
 244  signal ReadPktUARTRBitrateH : std_logic;
 245  signal LoadPktUARTRModeRegL : std_logic;
 246  signal ReadPktUARTRModeRegL : std_logic;
 247  signal LoadPktUARTRModeRegH : std_logic;
 248  signal ReadPktUARTRModeRegH : std_logic;
 249  -- TX UART signals
 250  signal LoadPktUARTTData : std_logic;
 251  signal LoadPktUARTTFrameCount : std_logic;
 252  signal ReadPktUARTTFrameCount : std_logic;
 253  signal LoadPktUARTTBitRateL : std_logic;
 254  signal ReadPktUARTTBitrateL : std_logic;
 255  signal LoadPktUARTTBitRateH : std_logic;
 256  signal ReadPktUARTTBitrateH : std_logic;
 257  signal LoadPktUARTTModeRegL : std_logic;
 258  signal ReadPktUARTTModeRegL : std_logic;
 259  signal LoadPktUARTTModeRegH : std_logic;
 260  signal ReadPktUARTTModeRegH : std_logic;
 261  signal PTXEn : std_logic;
 262  
 263  signal ForceReconfig : std_logic;
 264  signal ReconfigLatch	 : std_logic := '0';
 265  	
 266  signal ExtAddress: std_logic_vector(15 downto 0);	
 267  
 268  signal HM2obus	 : std_logic_vector(31 downto 0);
 269  signal HM2LEDs	 : std_logic_vector(LEDCount -1 downto 0);
 270  
 271  signal wseladd: std_logic_vector(7 downto 0); 
 272  signal rseladd: std_logic_vector(7 downto 0); 
 273  
 274  signal blinkcount : std_logic_vector(23 downto 0);
 275  
 276  signal clk0fx : std_logic;
 277  signal clk0 : std_logic;
 278  signal procclk : std_logic;
 279  
 280  signal clk1fx : std_logic;
 281  signal clk1 : std_logic;
 282  signal hm2fastclock : std_logic;
 283  
 284  -- crc16 signals
 285  signal NewXor: std_logic_vector(15 downto 0);
 286  signal LReadCRC: std_logic;
 287  signal LWriteCRC: std_logic;
 288  signal LClearCRC: std_logic;
 289  
 290  begin
 291  
 292  
 293  ahostmot2: entity work.HostMot2
 294  	generic map (
 295  		thepindesc => ThePinDesc,
 296  		themoduleid => TheModuleID,
 297  		idromtype  => IDROMType,		
 298  	   sepclocks  => SepClocks,
 299  		onews  => OneWS,
 300  		usestepgenprescaler => UseStepGenPrescaler,
 301  		useirqlogic  => UseIRQLogic,
 302  		pwmrefwidth  => PWMRefWidth,
 303  		usewatchdog  => UseWatchDog,
 304  		offsettomodules  => OffsetToModules,
 305  		offsettopindesc  => OffsetToPinDesc,
 306  		clockhigh  => ClockHigh,
 307  		clockmed => CLockMed,
 308  		clocklow  => ClockLow,
 309  		boardnamelow => BoardNameLow,
 310  		boardnamehigh => BoardNameHigh,
 311  		fpgasize  => FPGASize,
 312  		fpgapins  => FPGAPins,
 313  		ioports  => IOPorts,
 314  		iowidth  => IOWidth,
 315  		liowidth  => LIOWidth,
 316  		portwidth  => PortWidth,
 317  		buswidth  => BusWidth,
 318  		addrwidth  => AddrWidth,
 319  		inststride0 => InstStride0,
 320  		inststride1 => InstStride1,
 321  		regstride0 => RegStride0,
 322  		regstride1 => RegStride1,
 323  		ledcount  => LEDCount)
 324  	port map (
 325  		ibus =>  HM2WriteBuffer,
 326  		obus => HM2obus, 
 327  		addr => ExtAddress(15 downto 2),
 328  		readstb => Read32,
 329  		writestb => Write32,
 330  		clklow => procclk,
 331  		clkmed => procclk,			-- on 7I80 procclk is same as clocklow
 332  		clkhigh =>  hm2fastclock,
 333  --		int => INT, 
 334  		iobits => IOBITS,			
 335  		rates => Rates,
 336  		leds => HM2LEDS	
 337  
 338  		);
 339  
 340  	
 341  
 342  
 343  	ClockMult1 : DCM
 344  		generic map (
 345  			CLKDV_DIVIDE => 2.0,
 346  			CLKFX_DIVIDE => 2, 
 347  			CLKFX_MULTIPLY => 8,			-- 8/2 * 50 MHz = 200 mhz fast clock
 348  			CLKIN_DIVIDE_BY_2 => FALSE, 
 349  			CLKIN_PERIOD => 19.9,          
 350  			CLKOUT_PHASE_SHIFT => "NONE", 
 351  			CLK_FEEDBACK => "1X",         
 352  			DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", 
 353  															
 354  			DFS_FREQUENCY_MODE => "LOW",
 355  			DLL_FREQUENCY_MODE => "LOW",
 356  			DUTY_CYCLE_CORRECTION => TRUE,
 357  			FACTORY_JF => X"C080",
 358  			PHASE_SHIFT => 0, 
 359  			STARTUP_WAIT => FALSE)
 360  		port map (
 361  	
 362  			CLK0 => clk1,   	-- 
 363  			CLKFB => clk1,  	-- DCM clock feedback
 364  			CLKFX => clk1fx,
 365  			CLKIN => CLK,    	-- 50 Mhz source
 366  			PSCLK => '0',    	-- Dynamic phase adjust clock input
 367  			PSEN => '0',     	-- Dynamic phase adjust enable input
 368  			PSINCDEC => '0', 	-- Dynamic phase adjust increment/decrement
 369  			RST => '0'        -- DCM asynchronous reset input
 370  		);
 371    
 372  	BUFG1_inst : BUFG
 373  		port map (
 374  			O => hm2fastclock,    		-- Clock buffer output
 375  			I => clk1fx      				-- Clock buffer input
 376  		);
 377  
 378    -- End of DCM_inst instantiation
 379  	ClockMult2 : DCM
 380  		generic map (
 381   			CLKDV_DIVIDE => 2.0,
 382  			CLKFX_DIVIDE => 2, 
 383  			CLKFX_MULTIPLY =>4,					-- 4/2 100 MHz	interface clock
 384  			CLKIN_DIVIDE_BY_2 => FALSE, 
 385  			CLKIN_PERIOD => 19.9,          
 386  			CLKOUT_PHASE_SHIFT => "NONE", 
 387  			CLK_FEEDBACK => "1X",         
 388  			DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", 
 389  															
 390  			DFS_FREQUENCY_MODE => "LOW",
 391  			DLL_FREQUENCY_MODE => "LOW",
 392  			DUTY_CYCLE_CORRECTION => TRUE,
 393  			FACTORY_JF => X"C080",
 394  			PHASE_SHIFT => 0, 
 395  			STARTUP_WAIT => FALSE)
 396  		port map (
 397  	
 398  			CLK0 => clk0,   	-- 
 399  			CLKFB => clk0,  	-- DCM clock feedback
 400  			CLKFX => clk0fx,
 401  			CLKIN => CLK,    	-- Clock input (from IBUFG, BUFG or DCM)
 402  			PSCLK => '0',    	-- Dynamic phase adjust clock input
 403  			PSEN => '0',     	-- Dynamic phase adjust enable input
 404  			PSINCDEC => '0', 	-- Dynamic phase adjust increment/decrement
 405  			RST => '0'        -- DCM asynchronous reset input
 406  		);
 407    
 408  	BUFG2_inst : BUFG
 409  		port map (
 410  			O => procclk,    		-- Clock buffer output
 411  			I => clk0fx      						-- Clock buffer input
 412  		);
 413  
 414    -- End of DCM_inst instantiation
 415  
 416  	asimplspi: entity work.simplespi8
 417  		generic map
 418  		(
 419  			buswidth => 8,
 420  			div => 1,	-- for divide by 2 = 25 MHz
 421  			bits => 8
 422  		)	
 423  		port map 
 424  		( 
 425  			clk  => procclk,
 426  			ibus => mobus(7 downto 0),
 427  			obus => mibus_io(7 downto 0),
 428  			loaddata => LoadSPIReg,
 429  			readdata => ReadSPIReg,
 430  			loadcs => LoadSPICS,
 431  			readcs => ReadSPICS,
 432  			spiclk => SPIClk,
 433  			spiin => SPIIn,
 434  			spiout => SPIOut,
 435  			spics =>SPICS 
 436  		 );
 437  
 438  
 439  	processor: entity work.D16W
 440  	
 441  	port map (
 442  		clk     => procclk,
 443  		reset	  => '0',
 444  		iabus	  =>  iabus,		  -- program address bus
 445  		idbus	  =>  idbus,		  -- program data bus		 
 446  		mradd	  =>  mradd,		  -- memory read address
 447  		mwadd	  =>  mwadd,		  -- memory write address
 448  		mibus	  =>  mibus,		  -- memory data in bus	  
 449  		mobus	  =>  mobus,		  -- memory data out bus
 450  		mwrite  =>  mwrite,		  -- memory write signal	
 451        mread   =>  mread		     -- memory read signal	
 452  --		carryflg  =>				  -- carry flag
 453  		);
 454  
 455  
 456  	apktuartrx16: entity work.pktuartr16
 457  	generic map (MaxFrameSize => 1024) 		-- in bytes (-1) maximum is 2K bytes
 458  	port map (
 459  			clk => procclk,
 460  			ibus => mobus,
 461           obus => mibus_io,			
 462  			popdata => ReadPktUARTRData,
 463  			poprc=> ReadPktUARTRFrameCount,
 464  			loadbitratel => LoadPktUARTRBitRateL,
 465           readbitratel => ReadPktUARTRBitrateL,          
 466  			loadbitrateh => LoadPktUARTRBitRateH,
 467           readbitrateh => ReadPktUARTRBitrateH,          
 468  			loadmodel => LoadPktUARTRModeRegL,
 469  			readmodel => ReadPktUARTRModeRegL,
 470  			loadmodeh => LoadPktUARTRModeRegH,
 471  			readmodeh => ReadPktUARTRModeRegH,
 472  			rxmask => PTXEn,
 473  			rxdata => RXData
 474  			);
 475  
 476  	apktuarttx16: entity work.pktuartx16
 477  	generic map (MaxFrameSize => 1024) 		-- in bytes (-1) maximum is 2K bytes
 478  	port map (
 479  			clk => procclk,
 480  			ibus => mobus,
 481           obus => mibus_io,			
 482  			pushdata => LoadPktUARTTData,
 483  			pushsc => LoadPktUARTTFrameCount,
 484  			readsc => ReadPktUARTTFrameCount,
 485  			loadbitratel => LoadPktUARTTBitRateL,
 486           readbitratel => ReadPktUARTTBitrateL,          
 487  			loadbitrateh => LoadPktUARTTBitRateH,
 488           readbitrateh => ReadPktUARTTBitrateH,          
 489  			loadmodel => LoadPktUARTTModeRegL,
 490  			readmodel => ReadPktUARTTModeRegL,
 491  			loadmodeh => LoadPktUARTTModeRegH,
 492  			readmodeh => ReadPktUARTTModeRegH,
 493  			drven => PTXEn,
 494  			txdata => TXData
 495  			);
 496  
 497  
 498    Serialhm2 : entity work.serhm2
 499    port map(
 500  		addr => iabus(10 downto 0),
 501  		clk  => procclk,
 502  		din  => x"000000",
 503  		dout => idbus,
 504  		we	=> '0'
 505  	 );
 506  
 507  	DataRam : entity work.dpram 
 508  	generic map (
 509  		width => 16,
 510  		depth => 2048
 511  				)
 512  	port map(
 513  		addra => mwadd(10 downto 0),
 514  		addrb => mradd(10 downto 0),
 515  		clk  => procclk,
 516  		dina  => mobus,
 517  --		douta => 
 518  		doutb => mibus_ram,
 519  		wea	=> mwrite
 520  	 );	 
 521  	 
 522  	 
 523  	MiscProcFixes : process (procclk, mradd)		-- need to match BlockRAM address pipeline register for I/O
 524  	begin	
 525  		if rising_edge(procclk) then
 526  			ioradd <= mradd;
 527  		end if;
 528  	end process;		
 529  	
 530  	ram_iomux : process (ioradd(10),mibus_ram,mibus_io)
 531  	begin
 532  		if ioradd(11 downto 7) =  "00000" then 	-- bottom 128 bytes are I/O, notched into RAM
 533  			mibus <= mibus_io;
 534  		else
 535  			mibus <= mibus_ram;
 536  		end if;
 537  	end process;
 538  
 539  	iodecode: process(ioradd, mwadd, mwrite, rseladd, wseladd, extaddress,
 540  							writeextdata, readextdata, riosel, wiosel, mread)
 541  	begin
 542  		rseladd <= ioradd(7 downto 0);
 543  		wseladd <= mwadd(7 downto 0);
 544  		
 545  		if ioradd(10 downto 7) = x"0" then
 546  			riosel <= '1';
 547  		else
 548  			riosel <= '0';
 549  		end if;
 550  		
 551  		if mwadd(10 downto 7) = x"0" then
 552  			wiosel <= '1';
 553  		else
 554  			wiosel <= '0';
 555  		end if;
 556  		
 557  		if rseladd = x"20" and riosel = '1' then
 558  			LReadCRC <= '1';
 559  		else
 560  			LReadCRC <= '0';		
 561  		end if;	
 562  
 563  		if wseladd = x"20" and wiosel = '1' and mwrite = '1' then
 564  			LWriteCRC <= '1';
 565  		else
 566  			LWriteCRC <= '0';		
 567  		end if;	
 568  
 569  		if wseladd = x"21" and wiosel = '1' and mwrite = '1' then
 570  			LClearCRC<= '1';
 571  		else
 572  			LClearCRC<= '0';		
 573  		end if;	
 574  		
 575  		if rseladd = x"30" and riosel = '1' then
 576  			ReadPktUARTRData <= '1';
 577  		else
 578  			ReadPktUARTRData <= '0';		
 579  		end if;	
 580  
 581  		if rseladd = x"31" and riosel = '1' then
 582  			ReadPktUARTRFrameCount <= '1';
 583  		else
 584  			ReadPktUARTRFrameCount <= '0';		
 585  		end if;	
 586  		
 587  		if wseladd = x"32" and wiosel = '1' and mwrite = '1' then
 588  			LoadPktUARTRBitRateL <= '1';
 589  		else
 590  			LoadPktUARTRBitRateL <= '0';		
 591  		end if;	
 592  
 593  		if rseladd = x"32" and riosel = '1' then
 594  			ReadPktUARTRBitrateL <= '1';
 595  		else
 596  			ReadPktUARTRBitrateL <= '0';		
 597  		end if;	
 598  
 599  		if wseladd = x"33" and wiosel = '1' and mwrite = '1' then
 600  			LoadPktUARTRBitRateH <= '1';
 601  		else
 602  			LoadPktUARTRBitRateH <= '0';		
 603  		end if;	
 604  
 605  		if rseladd = x"33" and riosel = '1' then
 606  			ReadPktUARTRBitrateH <= '1';
 607  		else
 608  			ReadPktUARTRBitrateH <= '0';		
 609  		end if;	
 610  
 611  		if wseladd = x"34" and wiosel = '1' and mwrite = '1'then
 612  			LoadPktUARTRModeRegL <= '1';
 613  		else
 614  			LoadPktUARTRModeRegL <= '0';		
 615  		end if;	
 616  
 617  		if rseladd = x"34" and riosel = '1' then
 618  			ReadPktUARTRModeRegL <= '1';
 619  		else
 620  			ReadPktUARTRModeRegL <= '0';		
 621  		end if;	
 622  		
 623  		if wseladd = x"35" and wiosel = '1' and mwrite = '1'then
 624  			LoadPktUARTRModeRegH <= '1';
 625  		else
 626  			LoadPktUARTRModeRegH <= '0';		
 627  		end if;	
 628  
 629  		if rseladd = x"35" and riosel = '1' then
 630  			ReadPktUARTRModeRegH <= '1';
 631  		else
 632  			ReadPktUARTRModeRegH <= '0';		
 633  		end if;	
 634  
 635  		if wseladd = x"36" and wiosel = '1' and mwrite = '1'then
 636  			LoadPktUARTTData <= '1';
 637  		else
 638  			LoadPktUARTTData <= '0';		
 639  		end if;	
 640  
 641  		if wseladd = x"37" and wiosel = '1' and mwrite = '1'then
 642  			LoadPktUARTTFrameCount <= '1';
 643  		else
 644  			LoadPktUARTTFrameCount <= '0';		
 645  		end if;	
 646  
 647  		if rseladd = x"37" and riosel = '1' then
 648  			ReadPktUARTTFrameCount <= '1';
 649  		else
 650  			ReadPktUARTTFrameCount <= '0';		
 651  		end if;	
 652  		
 653  		if wseladd = x"38" and wiosel = '1' and mwrite = '1'then
 654  			LoadPktUARTTBitRateL <= '1';
 655  		else
 656  			LoadPktUARTTBitRateL <= '0';		
 657  		end if;	
 658  
 659  		if rseladd = x"38" and riosel = '1' then
 660  			ReadPktUARTTBitrateL <= '1';
 661  		else
 662  			ReadPktUARTTBitrateL <= '0';		
 663  		end if;	
 664  
 665  		if wseladd = x"39" and wiosel = '1' and mwrite = '1'then
 666  			LoadPktUARTTBitRateH <= '1';
 667  		else
 668  			LoadPktUARTTBitRateH <= '0';		
 669  		end if;	
 670  
 671  		if rseladd = x"39" and riosel = '1' then
 672  			ReadPktUARTTBitrateH <= '1';
 673  		else
 674  			ReadPktUARTTBitrateH <= '0';		
 675  		end if;	
 676  
 677  		if wseladd = x"3A" and wiosel = '1' and mwrite = '1'then
 678  			LoadPktUARTTModeRegL <= '1';
 679  		else
 680  			LoadPktUARTTModeRegL <= '0';		
 681  		end if;	
 682  
 683  		if rseladd = x"3A" and riosel = '1' then
 684  			ReadPktUARTTModeRegL <= '1';
 685  		else
 686  			ReadPktUARTTModeRegL <= '0';		
 687  		end if;	
 688  
 689  		if wseladd = x"3B" and wiosel = '1' and mwrite = '1'then
 690  			LoadPktUARTTModeRegH <= '1';
 691  		else
 692  			LoadPktUARTTModeRegH <= '0';		
 693  		end if;	
 694  
 695  		if rseladd = x"3B" and riosel = '1' then
 696  			ReadPktUARTTModeRegH <= '1';
 697  		else
 698  			ReadPktUARTTModeRegH <= '0';		
 699  		end if;	
 700  
 701  		if wseladd = x"3C" and wiosel = '1' and mwrite = '1'then
 702  			SetTPReg0 <= '1';
 703  		else
 704  			SetTPReg0 <= '0';		
 705  		end if;	
 706  
 707  		if wseladd = x"3D" and wiosel = '1' and mwrite = '1'then
 708  			ClrTPReg0 <= '1';
 709  		else
 710  			ClrTPReg0 <= '0';		
 711  		end if;	
 712  
 713  		if wseladd = x"3E" and wiosel = '1' and mwrite = '1'then
 714  			SetTPReg1 <= '1';
 715  		else
 716  			SetTPReg1 <= '0';		
 717  		end if;	
 718  
 719  		if wseladd = x"3F" and wiosel = '1' and mwrite = '1'then
 720  			ClrTPReg1 <= '1';
 721  		else
 722  			ClrTPReg1 <= '0';		
 723  		end if;	
 724  
 725  		if rseladd = x"3F" and riosel = '1' then
 726  			ReadOpts <= '1';
 727  		else
 728  			ReadOpts <= '0';		
 729  		end if;	
 730  
 731  		if wseladd = x"40" and wiosel = '1' and mwrite = '1' then
 732  			ForceReconfig <= '1';
 733  		else
 734  			ForceReconfig <= '0';		
 735  		end if;	
 736  		
 737  		
 738  		if rseladd (7 downto 2) = "011000" and riosel = '1' then -- 0x60 through 0x63
 739  			ReadExtData <= '1';
 740  		else
 741  			ReadExtData <= '0';		
 742  		end if;	
 743  
 744  		if wseladd (7 downto 2) = "011000" and wiosel = '1' and mwrite = '1' then -- 0x60 through 0x63
 745  			WriteExtData <= '1';
 746  		else
 747  			WriteExtData <= '0';		
 748  		end if;	
 749  
 750  		if rseladd = x"68" and riosel = '1' then
 751  			ReadExtAdd <= '1';
 752  		else
 753  			ReadExtAdd <= '0';		
 754  		end if;	
 755  
 756  		if wseladd = x"68" and wiosel = '1' and mwrite= '1' then
 757  			WriteExtAdd <= '1';
 758  		else
 759  			WriteExtAdd <= '0';		
 760  		end if;	
 761  
 762  		if wseladd = x"6C" and wiosel = '1' and mwrite = '1' then
 763  			StartExtRead <= '1';
 764  		else
 765  			StartExtRead <= '0';		
 766  		end if;	
 767  
 768  		if wseladd = x"6D" and wiosel = '1' and mwrite= '1' then
 769  			StartExtWrite <= '1';
 770  		else
 771  			StartExtWrite <= '0';		
 772  		end if;	
 773  	
 774  		if wseladd = x"6E" and wiosel = '1' and mwrite = '1' then
 775  			ExtAddrInc <= '1';
 776  		else
 777  			ExtAddrInc <= '0';		
 778  		end if;	
 779  
 780  		if rseladd = x"70" and riosel = '1' then
 781  			ReadRates <= '1';
 782  		else
 783  			ReadRates <= '0';		
 784  		end if;	
 785  		
 786  		if wseladd = x"79" and wiosel = '1' and mwrite = '1'then
 787  			WriteErrLED <= '1';
 788  		else
 789  			WriteErrLED <= '0';		
 790  		end if;	
 791  	
 792  
 793  		if wseladd = x"7A" and wiosel = '1' and mwrite = '1'then
 794  			WriteLEDs <= '1';
 795  		else
 796  			WriteLEDs <= '0';		
 797  		end if;	
 798  
 799  		if wseladd = x"7B" and wiosel = '1' and mwrite = '1'then
 800  			WriteLEDMode <= '1';
 801  		else
 802  			WriteLEDMode <= '0';		
 803  		end if;	
 804  
 805  		if rseladd = x"7C" and riosel = '1' then
 806  			ReadTimer <= '1';
 807  		else
 808  			ReadTimer <= '0';		
 809  		end if;	
 810  		
 811  		if wseladd = x"007D" and wiosel = '1' and mwrite = '1' then
 812  			LoadSPICS <= '1';
 813  		else
 814  			LoadSPICS <= '0';		
 815  		end if;	
 816  
 817  		if rseladd = x"007D" and riosel = '1' then
 818  			ReadSPICS <= '1';
 819  		else
 820  			ReadSPICS <= '0';		
 821  		end if;	
 822  
 823  		if wseladd = x"007E" and wiosel = '1' and mwrite = '1' then
 824  			LoadSPIReg <= '1';
 825  		else
 826  			LoadSPIReg <= '0';		
 827  		end if;	
 828  
 829  		if rseladd = x"007E" and riosel = '1' then
 830  			ReadSPIReg <= '1';
 831  		else
 832  			ReadSPIReg <= '0';		
 833  		end if;	
 834  		
 835  	end process iodecode;
 836  	
 837  		
 838  	SyncHM2InterfaceShim: process (procclk, readextdata,rseladd, 
 839  											 hm2readbuffer, startextwrite,
 840  											 readextadd,extaddress,ReadRates,
 841  											 Rates,ledmode,hm2leds,localleds,PTXEn )
 842  	begin	
 843  		if rising_edge(procclk) then
 844  			Read32 <= StartExtRead;
 845  		  	if WriteLEDS = '1' then
 846  				LocalLEDs <= mobus(1 downto 0);
 847  			end if;
 848  			
 849  		  	if WriteLEDMode = '1' then
 850  				LEDMode <= mobus(0);
 851  			end if;
 852  
 853  		  	if WriteErrLED = '1' then
 854  				LEDErrFF <= mobus(0);
 855  			end if;
 856  			
 857  			if WriteExtData = '1' then 
 858  				case wseladd(0) is
 859  					when'0' => HM2WriteBuffer(15 downto  0) <= mobus;
 860  					when'1' => HM2WriteBuffer(31 downto  16) <= mobus;
 861  					when others => null;
 862  				end case;
 863  			end if;
 864  
 865  			if WriteExtAdd = '1' then
 866  				ExtAddress <= mobus;
 867  			end if;	
 868  
 869  			if Read32 = '1' then
 870  				HM2ReadBuffer <= HM2OBus;
 871  			end if;	
 872  			
 873  
 874  			if (ExtAddrInc = '1') and (mobus(7) = '1') then -- hack to allow inc via lbp inc bit
 875  				ExtAddress <= ExtAddress +4;
 876  			end if;	
 877  			
 878  			
 879  		end if;	-- procclk
 880  	   Write32 <= StartExtWrite;
 881  		
 882  		mibus_io <= "ZZZZZZZZZZZZZZZZ";
 883  		
 884  		if ReadExtData = '1' then
 885  			case rseladd(0) is
 886  				when '0' => mibus_io <= HM2ReadBuffer(15 downto  0);
 887  				when '1' => mibus_io <= HM2ReadBuffer(31 downto  16);
 888  				when others => null;
 889  			end case;
 890  		end if;
 891  		
 892  		if ReadRates = '1' then
 893  			mibus_io(4 downto 0) <= Rates;
 894  		end if;	
 895  		
 896  		if ReadExtAdd = '1' then
 897  			mibus_io <= ExtAddress;
 898  		end if;
 899  
 900  		if LEDMode = '0' then
 901  			LEDS <= HM2LEDs;
 902  		else	
 903  			LEDS <= not LocalLEDs;
 904  		end if;	
 905  		TXEN <= PTXEn;		
 906  	end process;	
 907  	
 908  
 909  	uSTimer: process (procclk,ReadTimer,Timer) -- one usec timer
 910  	begin				
 911  		mibus_io <= "ZZZZZZZZZZZZZZZZ";
 912  		if ReadTimer = '1' then
 913  			mibus_io <= Timer;
 914  		end if;
 915  		if rising_edge(procclk) then			-- hardwired for divide by 100!!!
 916  			PreScale <= PreScale -1;
 917  			if PreScale(7) = '1' then
 918  				PreScale <= x"62";					-- modulo = n+2 = 100
 919  				Timer <= Timer +1;
 920  			end if;
 921  		end if;
 922  	end process uSTimer;	
 923  
 924  	crc16 : process (procclk,NewXor,LReadCRC) -- note CCITT (Kermit) X^16 + X^12 + X^5 + 1
 925  	variable crc: std_logic_vector(15 downto 0);	
 926  	begin		
 927  		crc := x"0000";
 928  		for i in 0 to 15 loop
 929  			if NewXor(i) = '1'  then
 930  				case i is					
 931  					when 0  => crc := crc xor x"8911"; 	-- crc of 1  
 932  					when 1  => crc := crc xor x"1223"; 	-- crc of 2
 933  					when 2  => crc := crc xor x"2446"; 	-- crc of 4
 934  					when 3  => crc := crc xor x"488C"; 	-- crc of 8
 935  					when 4  => crc := crc xor x"8110"; 	-- crc of 16
 936  					when 5  => crc := crc xor x"0221"; 	-- crc of 32 
 937  					when 6  => crc := crc xor x"0442"; 	-- crc of 64
 938  					when 7  => crc := crc xor x"0884"; 	-- crc of 128
 939  					when 8  => crc := crc xor x"D819"; 	-- crc of 256  
 940  					when 9  => crc := crc xor x"B033"; 	-- crc of 512
 941  					when 10 => crc := crc xor x"6067"; 	-- crc of 1024
 942  					when 11 => crc := crc xor x"C0CE"; 	-- crc of 2048
 943  					when 12 => crc := crc xor x"9195"; 	-- crc of 4096
 944  					when 13 => crc := crc xor x"3323"; 	-- crc of 8192 
 945  					when 14 => crc := crc xor x"6646"; 	-- crc of 16384
 946  					when 15 => crc := crc xor x"CC8C"; 	-- crc of 32768
 947  				end case;
 948  			else
 949  				crc := crc;
 950  			end if;
 951  		end loop;
 952  		if rising_edge(procclk) then
 953  			if LWriteCRC = '1' then
 954  				NewXor<= crc xor mobus;
 955  			end if;
 956  			if LClearCRC= '1' then
 957  				NewXor<= x"0000";
 958  			end if;
 959  		end if;
 960  		mibus_io <= (others => 'Z');
 961  		if LReadCRC = '1' then
 962  			mibus_io <= crc;
 963  		end if;
 964  	end process;		
 965  	
 966  
 967  	OptsDebug: process (procclk,OPTS,ReadOpts,TPReg)
 968  	begin
 969  				
 970  		mibus_io <= "ZZZZZZZZZZZZZZZZ";
 971  		if ReadOpts = '1' then
 972  			mibus_io(1 downto 0) <= OPTS;
 973  		end if;
 974  		
 975  		if rising_edge(procclk) then
 976  			if SetTPReg0 = '1' then
 977  				TPReg(0) <= '1';
 978  			end if;
 979  			if ClrTPReg0 = '1' then
 980  				TPReg(0) <= '0';
 981  			end if;
 982  			if SetTPReg1 = '1' then
 983  				TPReg(1) <= '1';
 984  			end if;
 985  			if ClrTPReg1 = '1' then
 986  				TPReg(1) <= '0';
 987  			end if;
 988  		end if;
 989  		TP <= TPReg;	
 990  	end process OptsDebug;	
 991  
 992  	doreconfig : process(procclk,ReconfigLatch)
 993  	begin
 994  		if rising_edge(procclk) then 
 995  			if ForceReconfig = '1' then
 996  				ReconfigLatch <= '1';
 997  			end if;	
 998  		end if;
 999  		if ReconfigLatch = '1' then
1000  			RECONFIG <= '0';
1001  		else
1002  			RECONFIG <= 'Z';
1003  		end if;
1004  	end process;	
1005  
1006  		
1007  	dofallback: if fallback generate -- do blinky red light to indicate failure to load primary bitfile
1008  		Fallbackmode : process(procclk)
1009  		begin
1010  			if rising_edge(procclk) then 
1011  				blinkcount <= blinkcount +1;
1012  			end if;
1013  			NINIT <= blinkcount(23);
1014  		end process;	
1015  	end generate;	
1016  		
1017  	donormal: if not fallback generate
1018  		NormalMode : process(LEDErrFF)
1019  		begin
1020  --			NINIT <= 'Z';
1021  			NINIT <= not LEDErrFF;
1022  		end process;	
1023  	end generate;		
1024  		
1025  
1026  
1027  end Behavioral;