OpenCores
URL https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [rtl/] [misclib/] [dcom_jtag.vhd] - Rev 5

Compare with Previous | Blame | View Log

--!
--! Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com
--!
--! Licensed under the Apache License, Version 2.0 (the "License");
--! you may not use this file except in compliance with the License.
--! You may obtain a copy of the License at
--!
--!     http://www.apache.org/licenses/LICENSE-2.0
--! Unless required by applicable law or agreed to in writing, software
--! distributed under the License is distributed on an "AS IS" BASIS,
--! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--! See the License for the specific language governing permissions and
--! limitations under the License.
--!
 
library ieee;
use ieee.std_logic_1164.all;
library commonlib;
use commonlib.types_common.all;
 
entity dcom_jtag is
  generic (
    irlen  : integer range 2 to 8 := 2;
    idcode : integer range 0 to 255 := 9;
    ainst  : integer range 0 to 255 := 2;  -- IR rw,address,size (35 bits)
    dinst  : integer range 0 to 255 := 3;  -- IR data (32 bits)
    id : std_logic_vector(31 downto 0) := X"01040093");
  port (
    rst         : in std_ulogic;
    tck         : in std_ulogic;
    tms         : in std_ulogic;
    tdi         : in std_ulogic;
    tdo         : out std_ulogic;
    tapi_tdo    : in std_ulogic;
    tapo_tck    : out std_ulogic;
    tapo_tdi    : out std_ulogic;
    tapo_inst   : out std_logic_vector(7 downto 0);
    tapo_rst    : out std_ulogic;
    tapo_capt   : out std_ulogic;
    tapo_shft   : out std_ulogic;
    tapo_upd    : out std_ulogic;
    tapo_xsel1  : out std_ulogic;
    tapo_xsel2  : out std_ulogic
    );
end;
 
 
architecture rtl of dcom_jtag is
 
  type ltap_out_type is record                           
    tck   : std_ulogic;
    tdi   : std_ulogic;
    inst  : std_logic_vector(7 downto 0);
    asel  : std_ulogic;
    dsel  : std_ulogic;
    reset : std_ulogic;
    capt  : std_ulogic;
    shift : std_ulogic;
    upd   : std_ulogic;     
  end record;
 
  constant BYPASS : std_logic_vector(irlen-1 downto 0) := (others => '1');
  constant IDCODE_I : std_logic_vector(irlen-1 downto 0) := conv_std_logic_vector(idcode, irlen);
 
  type state_type is (test_rst, run_idle, select_dr, capture_dr, shift_dr, exit1_dr,
                      pause_dr, exit2_dr, update_dr, select_ir, capture_ir, shift_ir,
                      exit1_ir, pause_ir, exit2_ir, update_ir); 
 
  type reg_type is record
   state  : state_type;
   inst   : std_logic_vector(irlen-1 downto 0);
   shft   : std_logic_vector(31 downto 0);
   tdo    : std_ulogic;
   sel_user1 : std_logic;
   sel_user2 : std_logic;
  end record;
 
  signal r, rin : reg_type;
 
begin 
 
  comb : process(tck, tms, tdi, tapi_tdo, r)   
    variable v : reg_type;
    variable vtapo : ltap_out_type;
    variable vtdo : std_ulogic;
  begin
 
    v := r; 
    vtapo.tck := tck;
    vtapo.reset := '0'; 
    vtapo.tdi := tdi;
    vtapo.inst := (others => '0'); 
    vtapo.inst(irlen-1 downto 0) := r.inst;
    vtapo.capt := '0'; 
    vtapo.upd := '0'; 
    vtapo.shift := '0'; 
    vtapo.asel := '0'; 
    vtapo.dsel := '0';
    if (r.inst = IDCODE_I) or (r.inst = BYPASS) then v.tdo := r.shft(0);
    else                                             v.tdo := tapi_tdo; end if;   
 
	    case r.state is
	      when test_rst   => if tms = '0' then v.state := run_idle; end if;
	      when run_idle   => if tms = '1' then v.state := select_dr; end if;
	      when select_dr  => if tms = '0' then v.state := capture_dr; else v.state := select_ir; end if;
	      when capture_dr => if tms = '0' then v.state := shift_dr; else v.state := exit1_dr; end if;
	      when shift_dr   => if tms = '1' then v.state := exit1_dr; end if;
	      when exit1_dr   => if tms = '0' then v.state := pause_dr; else v.state := update_dr; end if;
	      when pause_dr   => if tms = '1' then v.state := exit2_dr; end if;
	      when exit2_dr   => if tms = '0' then v.state := shift_dr; else v.state := update_dr; end if;
	      when update_dr  => if tms = '0' then v.state := run_idle; else v.state := select_dr; end if;
	      when select_ir  => if tms = '0' then v.state := capture_ir; else v.state := test_rst; end if;
	      when capture_ir => if tms = '0' then v.state := shift_ir; else v.state := exit1_ir; end if;
	      when shift_ir   => if tms = '1' then v.state := exit1_ir; end if;
	      when exit1_ir   => if tms = '0' then v.state := pause_ir; else v.state := update_ir; end if;
	      when pause_ir   => if tms = '1' then v.state := exit2_ir; end if;
	      when exit2_ir   => if tms = '0' then v.state := shift_ir; else v.state := update_ir; end if;
	      when update_ir  => if tms = '0' then v.state := run_idle; else v.state := select_dr; end if;
	    end case;
 
	    case r.state is
	      when test_rst =>
	        vtapo.reset := '1'; v.inst := IDCODE_I;
	      when capture_dr =>
	        vtapo.capt := '1';
	        if r.inst = BYPASS then v.shft(0) := '0'; end if;       
	        if r.inst = IDCODE_I then  v.shft := id; end if;
	      when shift_dr   =>
	        vtapo.shift := '1';
	        if r.inst = BYPASS then v.shft(0) := tdi; end if;
	        if r.inst = IDCODE_I then v.shft := tdi & r.shft(31 downto 1); end if;
	      when update_dr  =>
	        vtapo.upd := '1';
            v.sel_user1 := '0';
            v.sel_user2 := '0';
	      when capture_ir => 
	        v.shft(irlen-1 downto 2) := r.inst(irlen-1 downto 2); 
	        v.shft(1 downto 0) := "01";
   	      v.sel_user1 := '0';
  	       v.sel_user2 := '0';
	      when shift_ir   => 
	        v.shft(irlen-1 downto 0) := tdi & r.shft(irlen-1 downto 1);
	      when update_ir  => 
	        v.inst := r.shft(irlen-1 downto 0);
	        if r.shft(irlen-1 downto 0) = conv_std_logic_vector(ainst, irlen) then
	          v.sel_user1 := '1';
	          v.sel_user2 := '0';
          elsif r.shft(irlen-1 downto 0) = conv_std_logic_vector(dinst, irlen) then
	          v.sel_user1 := '0';
	          v.sel_user2 := '1';
          else 
	          v.sel_user1 := '0';
	          v.sel_user2 := '0';
          end if;
	      when others => 
	    end case;
 
	    rin <= v; 
 
	    tdo <= r.tdo;
	    tapo_tck <= tck;
      --if (r.sel_user1 or r.sel_user2)='1' then tapo_tck <= tck;
      --else                                     tapo_tck <= '1'; end if;
	    tapo_tdi <= tdi; 
	    tapo_inst <= vtapo.inst; 
	    tapo_rst <= vtapo.reset;
	    tapo_capt <= vtapo.capt; 
	    tapo_shft <= vtapo.shift; 
	    tapo_upd <= vtapo.upd;   
	    tapo_xsel1 <= r.sel_user1;
	    tapo_xsel2 <= r.sel_user2;
	  end process;
 
   posreg : process(tck, rst) begin
       if rising_edge(tck) then
	       r.state <= rin.state;
	       r.shft  <= rin.shft;
	     end if;
	     if rst = '0' then 
	       r.state <= test_rst; 
	       r.shft  <= id;
	     end if;
   end process;
 
   negreg : process(tck, rst) begin
	     if falling_edge(tck) then
	       r.inst <= rin.inst;
	       r.tdo  <= rin.tdo;
	       r.sel_user1 <= rin.sel_user1;
  	      r.sel_user2 <= rin.sel_user2;
	     end if;
	     if rst = '0' then 
	       r.inst <= IDCODE_I; 
	       r.sel_user1 <= '0';
   	     r.sel_user2 <= '0';
	     end if;
    end process; 
 
 
	end;  

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.