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

📄 tag2.vhd

📁 Xilinx_usb_jtag 下载器原理图及程序
💻 VHD
📖 第 1 页 / 共 2 页
字号:
		end loop;

		-- init TAP setup registers
		for tap in 0 to NUM_TAPS - 1 loop

			-- CONFIG1: TCK term A, TDO term off, all extra bits as inputs
			setup_reg(tap)(CONFIG1) <= "011000000000";
			
			-- CONFIG2: rst, trst, tristate inactive, clock = 1 MHz, different buffer for each			
			setup_reg(tap)(CONFIG2) <= "0011" & to_unsigned(tap, 4) & to_unsigned(11, 4);

		end loop;

	elsif rising_edge(usb_clk) then

		case cmd_state is
			
			when Idle =>
				reading_status <= false;
				reading_buf <= false;
				reading_ack <= false;

				if sync_rd = '1' then
					cmd_state <= PutCmd;
--				else

--					acking := false;

--					for cur in 0 to NUM_TAPS - 1 loop
--						if not acking then
--							if done_flagged(cur) = '1' then
--								acking := true;
--								done_ack(cur) <= '1';
--								ack_code <= "10100" & std_logic_vector(to_unsigned(cur, 3));
--								cmd_state <= GetAck_wait;
--								reading_ack <= true;
--							end if;
--						end if;
--					end loop;

--					if not acking then
--						done_ack <= (others => '0');
--					end if;

				end if;

			when PutCmd =>
				reg_num := to_integer(unsigned(usb_d(6 downto 4)));

				if usb_d(7) = '0' then
					-- action command
					case usb_d(6 downto 4) is

						when CMD_GETSTATUS =>
							reading_status <= true;
							cmd_state <= GetStatus_wait;

						when CMD_SETCURTAP =>
							cur_tap <= to_integer(unsigned(usb_d(3 downto 0)));
							cmd_state <= Idle;

						when CMD_WRBUF =>
							cmd_state <= PutBuf_wait;

						when CMD_RDBUF =>
							reading_buf <= true;
							cmd_state <= GetBuf_wait;

						when CMD_RUN =>
							want_tdi <= usb_d(0) = '1';
							want_tdo <= usb_d(1) = '1';
							want_pingTMS <= usb_d(2) = '1';
							cmd_state <= RunStart;

						when CMD_COPY =>
							reading_buf <= true;
							cmd_state <= Copy1;

						when CMD_DELAY =>
							cmd_state <= Delay;

						when others =>
							cmd_state <= Idle;

					end case;

				else

					-- Set register, either global or per-TAP-instance

					case usb_d(6 downto 4) is

						when "110" =>
							cur_setup_reg <= 0;
							setup_reg(cur_tap)(0)(11 downto 8) <= unsigned(usb_d(3 downto 0));
							cmd_state <= PutLowT_wait;

						when "111" =>
							cur_setup_reg <= 1;
							setup_reg(cur_tap)(1)(11 downto 8) <= unsigned(usb_d(3 downto 0));
							cmd_state <= PutLowT_wait;

						when "101" =>
							cmd_state <= Idle;	-- no-op

						when others =>
							cur_reg <= reg_num;
							reg(reg_num)(11 downto 8) <= unsigned(usb_d(3 downto 0));
							cmd_state <= PutLow_wait;

					end case;
				end if;

			when PutLow_wait =>
				if sync_rd = '1' then
					cmd_state <= PutLow;
				end if;
				
			when PutLow =>
				reg(cur_reg)(7 downto 0) <= unsigned(usb_d);
				cmd_state <= Idle;

			when PutLowT_wait =>
				if sync_rd = '1' then
					cmd_state <= PutLowT;
				else
					cmd_state <= PutLowT_wait;
				end if;
				
			when PutLowT =>
				setup_reg(cur_tap)(cur_setup_reg)(7 downto 0) <= unsigned(usb_d);
				cmd_state <= Idle;

			when RunStart =>
				if TAP_busy(cur_tap) = '0' then
					TAP_start(cur_tap) <= '1';	-- rising edge sets TAP_ack() = '1'
					cmd_state <= RunAck;
				end if;

			when RunAck =>
				if TAP_ack(cur_tap) = '0' then
					TAP_start(cur_tap) <= '0';
					cmd_state <= Idle;
				end if;

			when Copy1 =>
				if TAP_busy(cur_tap) = '0' then
					if reg(COUNT) = 0 then
						reading_buf <= false;
						cmd_state <= Idle;
					else
						cmd_state <= Copy2;
					end if;
				end if;

			when Copy2 =>
				cmd_state <= Copy1;
				reg(COUNT) <= reg(COUNT) - 1;
				reg(ADDR) <= reg(ADDR) + 1;

			when PutBuf_wait =>
				if TAP_busy(cur_tap) /= '0' then
					cmd_state <= PutBuf_wait;
				elsif reg(COUNT) = 0 then
					cmd_state <= Idle;
				elsif sync_rd = '1' then
					cmd_state <= PutBuf;
				end if;
				
			when PutBuf =>
				cmd_state <= PutBuf_wait;
				reg(COUNT) <= reg(COUNT) - 1;
				reg(ADDR) <= reg(ADDR) + 1;

			when GetStatus_wait =>
				if usb_txe_n = '0' then
					cmd_state <= GetStatus;
				end if;
				
			when GetAck =>
				cmd_state <= Idle;

			when GetAck_wait =>
				if usb_txe_n = '0' then
					cmd_state <= GetAck;
				end if;
				
			when GetStatus =>
				cmd_state <= Idle;

			when GetBuf_wait =>
				if TAP_busy(cur_tap) /= '0' then
					cmd_state <= GetBuf_wait;
				elsif reg(COUNT) = 0 then
					cmd_state <= Idle;
				elsif usb_txe_n = '0' then
					cmd_state <= GetBuf;
				end if;
				
			when GetBuf =>
				cmd_state <= GetBuf_wait;
				reg(COUNT) <= reg(COUNT) - 1;
				reg(ADDR) <= reg(ADDR) + 1;

			when Delay =>
				if reg(COUNT) = 0 then
					if reg(ADDR) = 0 then
--						ack_code <= "10101000";
--						cmd_state <= GetAck_wait;
						cmd_state <= Idle;
					else
						reg(ADDR) <= reg(ADDR) + 1;
						reg(COUNT) <= reg(COUNT) - 1;
					end if;
				else
					reg(COUNT) <= reg(COUNT) - 1;
				end if;			

			when others =>
				cmd_state <= Idle;

		end case;
	end if;
end process;

--===========================================================================
-- Buffers
--===========================================================================
-- for each TAP there is a dedicated input buffer.  Output buffers are in a
-- pool and TAPs can individually address them.  Not very efficient in terms
-- of muxes, but the resources are available.
-- p.s. 'input' here means in from jtag tdi, output means out to jtag tdo.
-----------------------------------------------------------------------------

tap_in_bufs: for idx in 0 to NUM_TAPS-1 generate
signal zero : std_logic_vector(7 downto 0);
signal reading : std_logic;

attribute INIT_00 : string;
attribute INIT_00 of in_buf : label is "00000000000000000000000000000000000000302E3156204741544A20425355"; -- 'USB JTAG V1.0'

begin
	zero <= (others => '0');
	reading <= '1' when reading_buf else '0';

	in_buf: RAMB4_S1_S8
-- synthesis translate_off
		generic map
			(INIT_00 => X"00000000000000000000000000000000000000302E3156204741544A20425355") -- 'USB JTAG V1.0'
-- synthesis translate_on
		port map
			(-- data coming from TAP tdi may be stored
			 DIA(0) => TAP_wr_data(idx),
			 ENA => TAP_wr_store(idx),
			 WEA => TAP_wr_store(idx),
			 RSTA => '0',
			 CLKA => TAP_wr_clk(idx),
			 ADDRA => std_logic_vector(TAP_wr_addr(idx)),
			 DOA => open,
			 
			 -- USB channel may access it via ADDR & COUNT registers and command CMD_RDBUF
			 DIB => zero,
			 ENB => reading,
			 WEB => '0',
			 RSTB => '0',
			 CLKB => usb_clk,
			 ADDRB => std_logic_vector(reg(ADDR)(BFAddr'left downto BFAddr'right)),
			 DOB => buf_rd_data(idx));
end generate;

tap_out_bufs: for idx in 0 to NUM_BUFS-1 generate
signal rdata : std_logic;
signal wdata : std_logic;
signal raddr : BVAddr;
signal sel_buf : integer range 0 to NUM_BUFS-1;
signal rclk : std_logic;
begin

	-- generate a tristate multiplexer for address, clock and data.  Effectively
	-- forms a crossbar with the outer loop.  Potential for internal bus contention.
	out_addr: for tap in 0 to NUM_TAPS-1 generate
	signal sel : boolean;
	begin
		sel <= to_integer(setup_reg(tap)(CONFIG2)(6 downto 4)) = idx;
		raddr <= TAP_rd_addr(tap) when sel else (others => 'Z');
		TAP_rd_data(tap) <= rdata when sel else 'Z';
		rclk <= TAP_rd_clk(tap) when sel else 'Z';
	end generate;

	-- write enable from USB channel - currently selected buffer and write data available
	wdata <= '1' when (to_integer(setup_reg(cur_tap)(CONFIG2)(6 downto 4)) = idx) and
							((cmd_state = Copy2) or (cmd_state = PutBuf)) else '0';

	out_buf: RAMB4_S1_S8
		port map
			(-- stored bits may be output to TAP tdo
			 DIA(0) => '0',
			 ENA => '1',
			 WEA => '0',
			 RSTA => '0',
			 CLKA => rclk,
			 ADDRA => std_logic_vector(raddr),
			 DOA(0) => rdata,
			 
			 -- bits may be written to through USB channel via COUNT & ADDR registers and
			 -- CMD_WRBUF command
			 DIB => usb_d,
			 ENB => wdata,
			 WEB => wdata,
			 RSTB => '0',
			 CLKB => usb_clk,
			 ADDRB => std_logic_vector(reg(ADDR)(BFAddr'left downto BFAddr'right)),
			 DOB => open);
end generate;

--===========================================================================
-- TAPs
--===========================================================================
-- For each set of wires, there is a TAP controller that handles the basic
-- coordination of clocks, signals and addresses.  Each runs independently,
-- so operations with multiple TAPs can overlap.
-----------------------------------------------------------------------------

taps: for cur in 0 to NUM_TAPS-1 generate

	component TAP is
		port
			(reset : in std_logic;
			 clk96 : in std_logic;
			 clk64 : in std_logic;
			 clk_select : in unsigned(3 downto 0);
			 busy : out std_logic;

			 tristate : in boolean;
			 TCK_term : in std_logic_vector(1 downto 0);
			 TDO_term : in std_logic;

			 run_start : in std_logic;
			 run_ack : buffer std_logic;
		 	 run_freerun : in std_logic;
			 run_bits : in unsigned(11 downto 0);
			 run_TMS : in unsigned(11 downto 0);
			 run_TDI : in boolean;
			 run_TDO : in boolean;
			 run_pingTMS : in boolean;

			 wr_clk : out std_logic;
			 wr_addr : buffer unsigned(11 downto 0);
			 wr_store : out std_logic;
			 wr_data : out std_logic;

			 rd_clk : out std_logic;
			 rd_addr : buffer unsigned(11 downto 0);
			 rd_data : in std_logic;

			 TCK : out std_logic_vector(1 downto 0);
			 TCK_fb : in std_logic;
			 TDI : out std_logic_vector(1 downto 0);
			 TMS : out std_logic;
			 TDO : in std_logic);
	end component;

	signal tristate : boolean;

begin

	tristate <= setup_reg(cur)(CONFIG2)(7) = '1';
	jtag_rst_n(cur) <= 'Z' when tristate else setup_reg(cur)(CONFIG2)(8);
	jtag_trst_n(cur) <= 'Z' when tristate else setup_reg(cur)(CONFIG2)(9);
	jtag_dint(cur) <= 'Z' when tristate else setup_reg(cur)(CONFIG2)(10);

	extra: if not DEBUG generate
	begin
		-- maintain jtag_extra() outputs
		extra_out: for idx in 0 to 3 generate
		begin
			jtag_extra(cur*4+idx) <= 'Z' when setup_reg(cur)(CONFIG1)(idx*2) = '0' else
			                         setup_reg(cur)(CONFIG1)(idx*2+1);
		end generate;
	end generate;

	a_TAP : TAP port map
		(reset => reset,
		 clk96 => clk_2,
		 clk64 => clk_1_5,
		 clk_select => setup_reg(cur)(CONFIG2)(3 downto 0),
		 busy => TAP_busy(cur),

		 tristate => tristate,
		 TCK_term => std_logic_vector(setup_reg(cur)(CONFIG1)(11 downto 10)),
		 TDO_term => setup_reg(cur)(CONFIG1)(9),

		 run_start => TAP_start(cur),
		 run_ack => TAP_ack(cur),
		 run_freerun => setup_reg(cur)(CONFIG2)(11),
		 run_bits => reg(BITS),
		 run_TMS => reg(TMS),
		 run_TDI => want_tdi,
		 run_TDO => want_TDO,
		 run_pingTMS => want_pingTMS,

		 wr_clk => TAP_wr_clk(cur),
		 wr_addr => TAP_wr_addr(cur),
		 wr_store => TAP_wr_store(cur),
		 wr_data => TAP_wr_data(cur),

		 rd_clk => TAP_rd_clk(cur),
		 rd_addr => TAP_rd_addr(cur),
		 rd_data => TAP_rd_data(cur),

		 TCK(0) => jtag_tck_A(cur),
		 TCK(1) => jtag_tck_B(cur),
		 TCK_fb => jtag_tck_fb(cur),
		 TMS => jtag_TMS(cur),
		 TDO => jtag_tdo(cur),
		 TDI(1) => jtag_tdi_term(cur),
		 TDI(0) => jtag_tdi(cur));


end generate;

end RTL;

⌨️ 快捷键说明

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