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

📄 jtag_control.vhd

📁 实用的程序代码
💻 VHD
📖 第 1 页 / 共 3 页
字号:
  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 + -