📄 jtag_control.vhd
字号:
signal data_cmd_n : std_logic;
signal load_Command : std_logic;
signal sel_n : std_logic;
constant No_Cmd_Bits : natural := 5;
signal command_shift : std_logic_vector(0 to 5);
signal Dbg_Reg_En_I : std_logic_vector(0 to 4);
signal shifting_Data : std_logic;
signal sync_word : std_logic_vector(1 to 8);
signal sync_word_shift : std_logic_vector(0 to 8);
signal sync_detected : std_logic;
signal sync : std_logic;
constant SYNC_CONST : std_logic_vector(sync_word'range) := "01101001";
signal Dbg_Update_I : std_logic;
signal execute : std_logic;
signal shift_Count : std_logic_vector(4 downto 0) := (others => '0');
subtype CMD_TYPE is std_logic_vector(1 to No_Cmd_Bits);
subtype CMD_RANGE is std_logic_vector(1 to 5);
signal command : CMD_TYPE;
-----------------------------------------------------------------------------
-- Register handling
-----------------------------------------------------------------------------
constant MB_READ_CONFIG : std_logic_vector(0 to 4) := "00111";
constant MB_WRITE_CONTROL : std_logic_vector(0 to 4) := "00001";
constant MB_WRITE_COMMAND : std_logic_vector(0 to 4) := "00010";
constant MB_READ_STATUS : std_logic_vector(0 to 4) := "00011";
constant MB_WRITE_ADDR : std_logic_vector(0 to 4) := "00100";
constant MB_WRITE_DATA : std_logic_vector(0 to 4) := "00101";
constant MB_READ_DATA : std_logic_vector(0 to 4) := "00110";
-- register "10000" to "11111" is pc breakpoints 1-16
-- Uart commands
constant MB_WRITE_BRK_RST_CTRL : std_logic_vector(0 to 4) := "01000";
constant UART_WRITE_BYTE : std_logic_vector(0 to 4) := "01001";
constant UART_READ_STATUS : std_logic_vector(0 to 4) := "01010";
constant UART_READ_BYTE : std_logic_vector(0 to 4) := "01011";
constant MDM_READ_CONFIG : std_logic_vector(0 to 4) := "01100";
constant MDM_WRITE_WHICH_MB : std_logic_vector(0 to 4) := "01101";
-- constant MDM_WRITE_WHICH_HW : std_logic_vector(0 to 4) := "01110";
constant MDM_READ_FROM_FSL : std_logic_vector(0 to 4) := "01110";
constant MDM_WRITE_TO_FSL : std_logic_vector(0 to 4) := "01111";
signal uart_TDO : std_logic;
signal tdo_reg : std_logic_vector(0 to C_UART_WIDTH-1);
signal status_reg : std_logic_vector(0 to 7);
signal set_Ext_BRK : std_logic := '0';
signal ext_BRK_i : std_logic := '0';
-- signal New_FSL_Data : std_logic := '0';
signal FSL_Write_OverRun : std_logic;
signal FSL_Read_UnderRun : std_logic;
-----------------------------------------------------------------------------
-- FIFO signals
-----------------------------------------------------------------------------
function largest (A : integer; B : integer) return integer is
begin -- function largest
if (A > B) then
return A;
else
return B;
end if;
end function largest;
-- Sharing the shifting of data between the UART and FSL to save area
constant Shift_Data_Size : integer := largest(C_UART_WIDTH, C_FSL_DATA_SIZE);
signal fifo_Write : std_logic := '0';
signal fifo_Din : std_logic_vector(0 to Shift_Data_Size-1);
signal rx_Data_Present_I : std_logic := '0';
signal rx_Buffer_Full_I : std_logic := '0';
signal fifo_Read : std_logic := '0';
signal fifo_DOut : std_logic_vector(0 to C_UART_WIDTH-1);
signal fifo_Data_Present : std_logic := '0';
signal tx_Buffer_Full_I : std_logic := '0';
-----------------------------------------------------------------------------
-- Internal signals for debugging
-----------------------------------------------------------------------------
signal Ext_NM_BRK_i : std_logic := '0';
signal Debug_SYS_Rst_i : std_logic := '0';
signal Debug_Rst_i : std_logic := '0';
begin -- architecture IMP
TDI_Sampling : process (DRCK) is
begin -- process TDI_Sampling
if DRCK'event and DRCK = '1' then -- rising clock edge
tdi_reg <= TDI;
end if;
end process TDI_Sampling;
-----------------------------------------------------------------------------
-- Control logic
-----------------------------------------------------------------------------
FDC_I : FDC
port map (
Q => data_cmd, -- [out std_logic]
C => Update, -- [in std_logic]
D => data_cmd_n, -- [in std_logic]
CLR => sel_n); -- [in std_logic]
data_cmd_n <= not data_cmd;
load_Command <= SHIFT and not data_cmd;
sel_n <= not SEL;
-----------------------------------------------------------------------------
-- Shift the command
-----------------------------------------------------------------------------
command_shift(0) <= tdi_reg;
Command_Regs : for I in 1 to No_Cmd_Bits generate
ShiftIn_Command_FDRE : FDRE
port map (
Q => command_shift(I), -- [out std_logic]
C => DRCK, -- [in std_logic]
CE => load_Command, -- [in std_logic]
D => command_shift(I-1), -- [in std_logic]
R => sel_n); -- [in std_logic]
Command_FDE : FDE
port map (
Q => command(I), -- [out std_logic]
C => DRCK, -- [in std_logic]
CE => data_cmd, -- [in std_logic]
D => command_shift(I) -- [in std_logic]
);
end generate Command_Regs;
Dbg_Reg_En_I <= command(CMD_RANGE'RANGE) when shifting_Data = '1' else "00000";
Dbg_Reg_En <= Dbg_Reg_En_I;
Dbg_TDI <= tdi_reg;
Dbg_Capture <= data_cmd_n;
Dbg_Update_I <= '1' when shift_Count(3 downto 0) = "1000" else '0';
Dbg_Update <= Dbg_Update_I;
-----------------------------------------------------------------------------
-- Shift in and try to detect the Sync Word
-----------------------------------------------------------------------------
sync_word_shift(0) <= tdi_reg;
Sync_Word_Regs : for I in sync_word'range generate
Sync_Word_FDR : FDR
port map (
Q => sync_word_shift(I), -- [out std_logic]
C => DRCK, -- [in std_logic]
D => sync_word_shift(I-1), -- [in std_logic]
R => data_cmd_n); -- [in std_logic]
end generate Sync_Word_Regs;
sync_word <= sync_word_shift(sync_word'range);
sync_detected <= '1' when sync_word = SYNC_CONST else '0';
SYNC_FDRE : FDRE
port map (
Q => sync, -- [out std_logic]
C => DRCK, -- [in std_logic]
CE => sync_detected, -- [in std_logic]
D => '1', -- [in std_logic]
R => data_cmd_n); -- [in std_logic]
shifting_Data <= SHIFT and sync;
-- Keep a counter on the number of bits in the data phase after a sync has
-- been detected
Shift_Counter : process (DRCK, Reset) is
begin -- process Shift_Counter
if DRCK'event and DRCK = '1' then -- rising clock edge
if data_cmd_n = '1' then
shift_Count <= (others => '0');
elsif shifting_Data = '1' then
shift_Count <= std_logic_vector(unsigned(Shift_Count) + 1);
end if;
end if;
end process Shift_Counter;
TDI_Register : process (DRCK) is
begin -- process TDI_Register
if DRCK'event and DRCK = '1' then -- rising clock edge
if shifting_Data = '1' then
fifo_Din(fifo_Din'left+1 to fifo_Din'right) <= fifo_Din(fifo_Din'left to fifo_Din'right-1);
fifo_Din(0) <= tdi_reg;
end if;
end if;
end process TDI_Register;
-----------------------------------------------------------------------------
-- Config Register handling
-----------------------------------------------------------------------------
SRL16E_1 : SRL16E
-- pragma translate_off
generic map (
INIT => Config_Init_Word
)
-- pragma translate_on
port map (
CE => '0', -- [in std_logic]
D => '0', -- [in std_logic]
Clk => DRCK, -- [in std_logic]
A0 => shift_Count(0), -- [in std_logic]
A1 => shift_Count(1), -- [in std_logic]
A2 => shift_Count(2), -- [in std_logic]
A3 => shift_Count(3), -- [in std_logic]
Q => config_TDO_1); -- [out std_logic]
SRL16E_2 : SRL16E
-- pragma translate_off
generic map (
INIT => Config_Init_Word2
)
-- pragma translate_on
port map (
CE => '0', -- [in std_logic]
D => '0', -- [in std_logic]
Clk => DRCK, -- [in std_logic]
A0 => shift_Count(0), -- [in std_logic]
A1 => shift_Count(1), -- [in std_logic]
A2 => shift_Count(2), -- [in std_logic]
A3 => shift_Count(3), -- [in std_logic]
Q => config_TDO_2); -- [out std_logic]
config_TDO <= config_TDO_1 when shift_Count(4) = '0' else config_TDO_2;
-- Mux the TDO depended on the source (set by the command)
TDO_Mux : process (uart_TDO, command, Dbg_TDO, config_TDO) is
begin -- process TDO_Mux
case command(CMD_RANGE'RANGE) is
when UART_READ_BYTE | UART_READ_STATUS => tdo <= uart_TDO;
when MDM_READ_CONFIG => tdo <= config_TDO;
when others => tdo <= Dbg_TDO;
end case;
end process TDO_Mux;
Execute_UART_Command : process (DRCK, data_cmd) is
begin -- process Execute_UART_Command
if data_cmd = '0' then -- asynchronous reset (active low)
execute <= '0';
elsif DRCK'event and DRCK = '1' then -- rising clock edge
if shifting_Data = '1' then
if (shift_count(3 downto 0) = "1001") then
if (Command(CMD_RANGE'RANGE) = UART_READ_BYTE) or
(Command(CMD_RANGE'RANGE) = UART_WRITE_BYTE) or
(Command(CMD_RANGE'range) = UART_READ_STATUS) or
(Command(CMD_RANGE'range) = MB_WRITE_BRK_RST_CTRL) then
execute <= '1';
else
execute <= '0';
end if;
end if;
end if;
end if;
end process Execute_UART_Command;
Execute_FIFO_Command : process (OPB_Clk) is
variable execute_1 : std_logic;
variable execute_2 : std_logic;
begin -- process Execute_FIFO_Command
if OPB_Clk'event and OPB_Clk = '1' then -- rising clock edge
fifo_Write <= '0';
fifo_Read <= '0';
set_Ext_BRK <= '0';
Ext_NM_BRK_i <= '0';
if (execute_2 = '0') and (execute_1 = '1') then -- rising edge
if (command(CMD_RANGE'range) = MB_WRITE_BRK_RST_CTRL) then
-- Debug_Rst_i <= fifo_Din(4);
-- Debug_SYS_Rst_i <= fifo_Din(5);
-- set_Ext_BRK <= fifo_Din(6);
-- Ext_NM_BRK_i <= fifo_Din(7);
Debug_Rst_i <= fifo_Din(0);
Debug_SYS_Rst_i <= fifo_Din(1);
set_Ext_BRK <= fifo_Din(2);
Ext_NM_BRK_i <= fifo_Din(3);
end if;
if (command(CMD_RANGE'RANGE) = UART_WRITE_BYTE) then
fifo_Write <= '1';
end if;
if (command(CMD_RANGE'RANGE) = UART_READ_BYTE) then
fifo_Read <= '1';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -