⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ocdprogtck.vhd

📁 AVR IP core writen in VHDL. It is beta version, working even with AVR studio
💻 VHD
📖 第 1 页 / 共 2 页
字号:
--**********************************************************************************************
-- JTAG	"Flash" programmer for AVR Core(TCK Clock Domain)
-- Version 0.4
-- Modified 20.06.2006
-- Designed by Ruslan Lepetenok
--**********************************************************************************************

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

use WORK.JTAGPack.all;
use WORK.JTAGProgrammerPack.all;
use WORK.JTAGDataPack.all;
use WORK.JTAGTAPCtrlSMPack.all;

entity OCDProgTCK is port(
						  -- JTAG related inputs/outputs
						  TRSTn             : in  std_logic; -- Optional
	                      TMS               : in  std_logic;
                          TCK	            : in  std_logic;
                          TDI               : in  std_logic;
                          TDO               : out std_logic;
						  TDO_OE            : out std_logic;
						  -- From/To cp2 clock domain("Flash" programmer) 
						  FlEEPrgAdr        : out std_logic_vector(15 downto 0);
						  FlPrgRdData       : in  std_logic_vector(15 downto 0);
						  EEPrgRdData       : in  std_logic_vector(7 downto 0);
                          FlEEPrgWrData     : out std_logic_vector(15 downto 0);
						  ChipEraseStart    : out std_logic;
						  ChipEraseDone     : in  std_logic;
						  ProgEnable        : out std_logic;
						  FlWrMStart        : out std_logic;  -- Multiple 
						  FlWrSStart        : out std_logic;  -- Single 
						  FlRdMStart        : out std_logic;  -- Multiple 
						  FlRdSStart	    : out std_logic;  -- Single 
						  EEWrStart         : out std_logic;
						  EERdStart         : out std_logic;
						  TAPCtrlTLR        : out std_logic; -- TAP Controller is in the Test-Logic/Reset state
						  -- CPU reset
						  jtag_rst          : out std_logic
                          );
end OCDProgTCK;

architecture RTL of OCDProgTCK is

signal CurrentTAPState    : TAPCtrlState_Type;
signal NextTAPState       : TAPCtrlState_Type;

-- JTAG Registers
-- Instruction registers
signal InstructionShRg    : std_logic_vector(CInstrLength-1 downto 0); -- Shift
signal InstructionRg      : std_logic_vector(CInstrLength-1 downto 0); -- Update

-- Bypass register
signal BypassShRg         : std_logic; -- Shift(only)


-- **********************************************************************
signal IDCODEShRg         : std_logic_vector(31 downto 0);

signal DataRegsOutMux     : std_logic;

signal UnusedInstr        : std_logic; -- Unsupported instruction

-- Reset chain (1 bit length, no updade register)
signal ResetShRg : std_logic; 

-- ************************* Programmer part ********************************************
-- Program chains
signal PERSh : std_logic_vector(15 downto 0); -- Programming Enable Register (Shift part ?only?)

signal PCRSh    : std_logic_vector(14 downto 0); -- Programming Command Register (Shift part)
signal PCRUd    : std_logic_vector(PCRSh'range); -- Programming Command Register (Update part)
signal PCRShIn  : std_logic_vector(PCRSh'range); -- Programming Command Register Input

signal VFPLSh   : std_logic_vector(7 downto 0); -- Virtual Flash Page Load Register (Shift part only)
signal VFPRSh   : std_logic_vector(7 downto 0); -- Virtual Flash Page Read Register (Shift part only)
signal VFPRShIn : std_logic_vector(VFPRSh'range); -- Virtual Flash Page Read Register Input

signal ProgEnable_Int : std_logic;

-- TCK counter for Virtual Flash Page Load/Read commands
signal VFPCnt         : std_logic_vector(3 downto 0);
signal LdDataLow      : std_logic; -- Load low byte of data
signal LdDataHigh     : std_logic; -- Load high byte of data and runs "Flash" write SM(cp2 clock domain)
signal FlashAdrIncrEn : std_logic; -- Enables increment of VFPCnt (when LdDataHigh='1')
signal LatchWrData    : std_logic; 

-- Address(16-bit) and Instruction For Write (16-bit) registers located in TCK clock domaim 
signal FlEEPrgAdr_Int     : std_logic_vector(15 downto 0); -- Copy of output

-- Address counter length
constant CPageAdrCntLength : positive range 7 to 8 := 7; -- 8 for ATmega128, 7 for ATmega16,...  

-- "Flash" programmer state machines (located in TCK clock domaim)	
type ChipEraseSMStType is (ChipEraseSMStIdle,ChipEraseSMSt1,ChipEraseSMSt2,ChipEraseSMSt3);
signal ChipEraseSM_CurrentState : ChipEraseSMStType;	-- Chip erase 
signal ChipEraseSM_NextState    : ChipEraseSMStType;	-- Chip erase (combinatorial)

signal FlashWr_St            : std_logic; -- 2
signal FlashRd_St            : std_logic; -- 3
signal EEPROMWr_St           : std_logic; -- 4
signal EEPROMRd_St           : std_logic; -- 5
signal FuseWr_St             : std_logic; -- 6
signal LockWr_St             : std_logic; -- 7
signal FuseLockRd_St         : std_logic; -- 8
signal SignByteRd_St         : std_logic; -- 9

signal LoadNOP_St            : std_logic; -- 11 

-- EEPROM Write Support
signal EEWrStart_Int         : std_logic;
signal EERdStart_Int         : std_logic;	  

begin
	
TAPStateReg:process(TCK,TRSTn)
begin
 if(TRSTn='0')  then                 -- Reset
  CurrentTAPState <= TestLogicReset;
 elsif(TCK='1' and TCK'event)  then -- Clock(rising edge)
  CurrentTAPState <= NextTAPState;
 end if;
end process;			


NextTAPState <= FnTAPNextState(CurrentTAPState,TMS);

-- Instruction register
InstructionRegisterShift:process(TCK,TRSTn)
begin
 if(TRSTn='0') then                 -- Reset
  InstructionShRg <= (others => '0');
 elsif(TCK='1' and TCK'event) then  -- Clock(rising edge)
  case CurrentTAPState is 
   --when CaptureIR => InstructionShRg <= InstructionRg(InstructionRg'high downto 2)&"01"; -- !!! TBD !!!
   when CaptureIR => InstructionShRg <= InstructionRg; -- !!! TBD !!!
   when	ShiftIR   => InstructionShRg <= FnJTAGRgSh(InstructionShRg,TDI);
   when others    => null;
  end case;
end if;
end process;			

InstructionRegisterUpdate:process(TCK,TRSTn)
begin
if (TRSTn='0') then                 -- Reset
  InstructionRg <= CInitInstrRegVal;
elsif (TCK='0' and TCK'event) then  -- Clock(falling edge)
  if (CurrentTAPState=TestLogicReset) then 
   InstructionRg <= CInitInstrRegVal;	-- Set to give IDCODE or BYPASS instruction  
  elsif CurrentTAPState=UpdateIR then   
   InstructionRg <= InstructionShRg;
  end if;
end if;
end process;			

-- Data registers

-- ID Code register
IDCodeRegisterShift:process(TCK,TRSTn)
begin
 if (TRSTn='0') then                 -- Reset
  IDCODEShRg <= (others => '0');
 elsif (TCK='1' and TCK'event)  then  -- Clock(rising edge)
  if (InstructionRg=C_IDCODE) then      -- The Instruction register content enables The Data register shift
   case CurrentTAPState is 
    when CaptureDR => IDCODEShRg <= CVersion&CPartNumber&CManufacturerId&'1'; 
    when ShiftDR   => IDCODEShRg <= FnJTAGRgSh(IDCODEShRg,TDI);
    when others    => null;
   end case;
  end if;
 end if;
end process;		

-- Bypass register
BypassRegisterShift:process(TCK,TRSTn)
begin
 if (TRSTn='0')  then                 -- Reset
  BypassShRg <= '0';
 elsif (TCK='1' and TCK'event)  then  -- Clock(rising edge)
  if (InstructionRg=C_BYPASS) then -- !!! TBD !!!
   case CurrentTAPState is 
    when ShiftDR => BypassShRg <= TDI;	 
    when others  => BypassShRg <= '0';  -- ??? TBD
   end case;
  end if;
 end if;
end process;			


DORegAndTDOOE:process(TCK,TRSTn)
begin
 if (TRSTn='0')  then                 -- Reset
  TDO <= '0';
  TDO_OE <= '0';  
 elsif  (TCK='0' and TCK'event)  then -- Clock(falling edge)
  TDO <= DataRegsOutMux;
  if (CurrentTAPState=ShiftIR or CurrentTAPState=ShiftDR) then
   TDO_OE <= '1'; 
  else
   TDO_OE <= '0';
  end if;	 
 end if;
end process;							  

-- ***************************************************************************************

UnusedInstr <= '1' when (InstructionRg=C_UNUSED_3 or InstructionRg=C_UNUSED_D or
                        InstructionRg=C_UNUSED_E or InstructionRg=C_OCD_ACCESS or InstructionRg= C_EX_INST) else '0';
							
DataRegsOutMux <= InstructionShRg(InstructionShRg'low) when CurrentTAPState=ShiftIR else -- !!! TBD !!!
				  '0' when InstructionRg=C_SAMPLE_PRELOAD or InstructionRg=C_EXTEST else -- !!! TBD !!!
				  IDCODEShRg(IDCODEShRg'low) when InstructionRg=C_IDCODE else
				  ResetShRg when InstructionRg=C_AVR_RESET else
				  PERSh(PERSh'low) when InstructionRg=C_PROG_ENABLE else
				  PCRSh(PCRSh'low) when InstructionRg=C_PROG_COMMANDS else
				  VFPLSh(VFPLSh'low) when InstructionRg=C_PROG_PAGELOAD else	  
				  VFPRSh(VFPRSh'low) when InstructionRg=C_PROG_PAGEREAD else	  	  
				  BypassShRg;				  
				  
-- ***************************************************************************************
	  
				  
-- Reset chain (1 bit length, no updade register)				  
ResetRegisterShift:process(TCK)
begin
 if(TCK='1' and TCK'event)  then  -- Clock(rising edge)
  if(InstructionRg=C_AVR_RESET and CurrentTAPState=ShiftDR) then 
   ResetShRg <= TDI;	 
  end if;
 end if;
end process;	

jtag_rst <= ResetShRg; 


-- ************************************************************************************
-- ************************* Programmer part ********************************************
-- ************************************************************************************

-- Programming Enable Register(no update circuit)
PER_Shift:process(TCK)
begin
 if(TCK='1' and TCK'event)  then  -- Clock(rising edge)
  if(InstructionRg=C_PROG_ENABLE and CurrentTAPState=ShiftDR) then 
   PERSh <= FnJTAGRgSh(PERSh,TDI);
  end if;
 end if;
end process;	

-- Programming enable signal generation(!!! TBD !!!)
PE_Gen_Rg:process(TCK)
begin
 if(TCK='0' and TCK'event)  then  -- Clock(falling edge)
  if(InstructionRg=C_PROG_ENABLE and CurrentTAPState=UpdateDR) then -- ???
   if(PERSh=C_ProgEnableVect) then
	ProgEnable_Int <= '1';
   else	
    ProgEnable_Int <= '0';
   end if;	
  end if;
 end if;
end process;	

-- Programming Command Register
PCR_Shift:process(TCK)
begin
 if(TCK='1' and TCK'event)  then  -- Clock(rising edge)
  if(InstructionRg=C_PROG_COMMANDS) then 
   case CurrentTAPState is 
    when CaptureDR => PCRSh <= PCRShIn; -- Load data
    when ShiftDR   => PCRSh <= FnJTAGRgSh(PCRSh,TDI);
    when others    => null;
   end case;
  end if;
 end if;
end process;	


PCRShIn(14 downto 10) <= PCRSh(14 downto 10);	
PCRShIn(8) <= PCRSh(8);	

-- Poll response  !!!TBD!!!
PCRShIn(9) <= '0' when (ChipEraseSM_CurrentState /= ChipEraseSMStIdle) else '1';	

	
PCRReadSystem:process(TCK)
begin
if(TCK='1' and TCK'event)  then  -- Clock(rising edge)
 if(CurrentTAPState=UpdateDR and InstructionRg=C_PROG_COMMANDS) then 	
	 
  if(FlashRd_St='1') then     -- Flash read	 
   if(PCRSh=C_Prg_3D_1) then	  
	 PCRShIn(7 downto 0) <= FlPrgRdData(7 downto 0); -- Read low flash byte
   elsif(PCRSh=C_Prg_3D_2) then	 
	 PCRShIn(7 downto 0) <= FlPrgRdData(15 downto 8); -- Read high flash byte
   end if;	 
   
  elsif(EEPROMRd_St='1') then -- EEPROM read	 
   if(PCRSh=C_Prg_5D_2) then	 
	PCRShIn(7 downto 0) <= EEPrgRdData; 
   end if;	 
   
  elsif(FuseLockRd_St='1') then -- Fuse/Lock bit Read Mode(8)
   case PCRSh  is  -- !!!TBD!!! (Length) 	
	when C_Prg_8B_1 =>  -- 8b(8f1) Read Extended Fuse Byte
	 PCRShIn(7 downto 0) <= C_ExtFuseByte;
	when C_Prg_8C_1 =>  -- 8c(8f2) Read Fuse High Byte
	 PCRShIn(7 downto 0) <= C_HighFuseByte;
	when C_Prg_8D_1 =>  -- 8d(8f3) Read Fuse Low Byte
	 PCRShIn(7 downto 0) <= C_LowFuseByte;
	when C_Prg_8E_1 =>  -- 8e(8f4) Read Lock Bits
	 PCRShIn(7 downto 0) <= C_LockBits;
	when others => null;
   end case;	 
   
  elsif (SignByteRd_St='1') then -- Signature Byte Read  Mode(9/10)
   if(PCRSh=C_Prg_9C_1) then -- Read Signature Byte(9c) -> 0110010_00000000
    case FlEEPrgAdr_Int(3 downto 0) is  -- !!!TBD!!! (Length) 	
	 when x"0" => PCRShIn(7 downto 0) <= C_SignByte1;
	 when x"1" => PCRShIn(7 downto 0) <= C_SignByte2;
	 when x"2" => PCRShIn(7 downto 0) <= C_SignByte3;
	 when others => null;
    end case;
	
   elsif(PCRSh=C_Prg_10C_1) then -- Read Calibration Byte(10c) -> 0110110_00000000
    case FlEEPrgAdr_Int(3 downto 0) is  -- !!!TBD!!! (Length) 	
	 when x"0" => PCRShIn(7 downto 0) <= C_CalibrByte1;
	 when x"1" => PCRShIn(7 downto 0) <= C_CalibrByte2;
	 when x"2" => PCRShIn(7 downto 0) <= C_CalibrByte3;
     when x"3" => PCRShIn(7 downto 0) <= C_CalibrByte4;
	 when others => null;
    end case;   
   
   end if;
   
  end if;   
 end if;   
end if;
end process;		
	

PCR_Update:process(TCK)
begin
 if(TCK='0' and TCK'event)  then  -- Clock(falling edge)
  if (CurrentTAPState=UpdateDR and InstructionRg=C_PROG_COMMANDS) then -- Clock enable (!!!InstructionRg=C_PROG_COMMANDS!!!)
   PCRUd <= PCRSh;
  end if;
 end if;
end process;	


-- Virtual Flash Page Load Register(!!!shift only!!!)
VFPL_Shift:process(TCK)
begin
 if(TCK='1' and TCK'event)  then  -- Clock(rising edge)
  if(InstructionRg=C_PROG_PAGELOAD and CurrentTAPState=ShiftDR) then 
   VFPLSh <= FnJTAGRgSh(VFPLSh,TDI);
  end if;
 end if;
end process;	

-- !!! TBD !!!
VFPRShIn <= FlPrgRdData(7 downto 0) when VFPCnt(VFPCnt'high)='0' else -- Low Byte
	        FlPrgRdData(15 downto 8);                                 -- High Byte

			
-- Virtual Flash Page Read Register
VFPR_Shift:process(TCK)
begin
 if(TCK='1' and TCK'event)  then  -- Clock(rising edge)
  if((VFPCnt=x"7" or VFPCnt=x"F"))then -- Load Data (Low/High Byte) !!!TBD!!!
   VFPRSh <= VFPRShIn; -- Load data
  elsif(InstructionRg=C_PROG_PAGEREAD and CurrentTAPState=ShiftDR) then 
   VFPRSh <= FnJTAGRgSh(VFPRSh,TDI);
  end if;
 end if;
end process;	


-- TCK counter for Virtual Flash Page Load/Read commands 
VFPCounterReg:process(TCK)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -