forked from cores/microwatt
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
2.6 KiB
VHDL
106 lines
2.6 KiB
VHDL
5 years ago
|
library ieee;
|
||
|
use ieee.std_logic_1164.all;
|
||
|
use ieee.numeric_std.all;
|
||
|
|
||
|
library work;
|
||
|
use work.sim_jtag_socket.all;
|
||
|
|
||
|
library unisim;
|
||
|
use unisim.vcomponents.all;
|
||
|
|
||
|
entity sim_jtag is
|
||
|
end sim_jtag;
|
||
|
|
||
|
architecture behaviour of sim_jtag is
|
||
|
begin
|
||
|
jtag: process
|
||
|
-- Global JTAG signals (used by BSCANE2 inside dmi_dtm
|
||
|
alias j : glob_jtag_t is glob_jtag;
|
||
|
|
||
|
-- Super fast JTAG clock for sim. For debugging the JTAG module,
|
||
|
-- change this to something much larger, for example 60ns, to reflect
|
||
|
-- more realistic conditions.
|
||
|
constant jclk_period : time := 1 ns;
|
||
|
|
||
|
-- Polling the socket... this could be made slower when nothing
|
||
|
-- is connected once we have that indication from the C code.
|
||
|
constant poll_period : time := 100 ns;
|
||
|
|
||
|
-- Number of dummy JTAG clocks to inject after a command. (I haven't
|
||
|
-- got that working with UrJtag but at least with sim, having the
|
||
|
-- right number here allows the synchronizers time to complete a
|
||
|
-- command on the first message exchange, thus avoiding the need
|
||
|
-- for two full shifts for a response.
|
||
|
constant dummy_clocks : integer := 80;
|
||
|
|
||
|
procedure clock(count: in INTEGER) is
|
||
|
begin
|
||
|
for i in 1 to count loop
|
||
|
j.tck <= '0';
|
||
|
wait for jclk_period/2;
|
||
|
j.tck <= '1';
|
||
|
wait for jclk_period/2;
|
||
|
end loop;
|
||
|
end procedure clock;
|
||
|
|
||
|
procedure clock_command(cmd: in std_ulogic_vector;
|
||
|
rsp: out std_ulogic_vector) is
|
||
|
begin
|
||
|
j.capture <= '1';
|
||
|
clock(1);
|
||
|
j.capture <= '0';
|
||
|
clock(1);
|
||
|
j.shift <= '1';
|
||
|
for i in 0 to cmd'length-1 loop
|
||
|
j.tdi <= cmd(i);
|
||
|
rsp := rsp(1 to rsp'length-1) & j.tdo;
|
||
|
clock(1);
|
||
|
end loop;
|
||
|
j.shift <= '0';
|
||
|
j.update <= '1';
|
||
|
clock(1);
|
||
|
j.update <= '0';
|
||
|
clock(1);
|
||
|
end procedure clock_command;
|
||
|
|
||
|
variable cmd : std_ulogic_vector(0 to 247);
|
||
|
variable rsp : std_ulogic_vector(0 to 247);
|
||
|
variable msize : std_ulogic_vector(7 downto 0);
|
||
|
variable size : integer;
|
||
|
|
||
|
begin
|
||
|
|
||
|
-- init & reset
|
||
|
j.reset <= '1';
|
||
|
j.sel <= "0000";
|
||
|
j.capture <= '0';
|
||
|
j.update <= '0';
|
||
|
j.shift <= '0';
|
||
|
j.tdi <= '0';
|
||
|
j.tms <= '0';
|
||
|
j.runtest <= '0';
|
||
|
clock(5);
|
||
|
j.reset <= '0';
|
||
|
clock(5);
|
||
|
|
||
|
-- select chain USER2
|
||
|
-- XXX TODO: Send that via protocol instead
|
||
|
-- XXX TODO: Also maybe have the C code tell us if connected or not
|
||
|
-- and clock when connected.
|
||
|
j.sel <= "0010";
|
||
|
clock(1);
|
||
|
rsp := (others => '0');
|
||
|
while true loop
|
||
|
wait for poll_period;
|
||
|
sim_jtag_read_msg(cmd, msize);
|
||
|
size := to_integer(unsigned(msize));
|
||
|
if size /= 0 and size < 248 then
|
||
|
clock_command(cmd(0 to size-1),
|
||
|
rsp(0 to size-1));
|
||
|
sim_jtag_write_msg(rsp, msize);
|
||
|
clock(dummy_clocks);
|
||
|
end if;
|
||
|
end loop;
|
||
|
end process;
|
||
|
end;
|