URL
https://opencores.org/ocsvn/openjtag-project/openjtag-project/trunk
Subversion Repositories openjtag-project
[/] [openjtag-project/] [trunk/] [OpenJTAG/] [Quartus_II/] [serializer.vhd] - Rev 18
Compare with Previous | Blame | View Log
-- Created by Ruben H. Mileca - May-16-2010 library ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.all; entity serializer IS port ( -- Internal clk: in std_logic; -- External 24 MHz oscillator -- FT245BM txe: in std_logic; -- From FT245BM TXE# pin rxf: in std_logic; -- From FT245BM RXF pin pwr: in std_logic; -- From FT245BM PWREN# pin rst: in std_logic; -- From FT245BM RSTOUT# pin wrk: in std_logic; -- From tap_sm working signal wr: out std_logic := '1'; -- To FT245BM WR pin rd: out std_logic := '1'; -- To FT245BM RD# pin siwu: out std_logic := '1'; -- To FT245BM SI/WU pin db: inout std_logic_vector(7 downto 0); -- From/To FT245BM data bus -- JTAG tdo: in std_logic; -- TDO Jtag pin tck: out std_logic := '0'; -- TCK Jtag pin tms: out std_logic := '0'; -- TMS Jtag pin tdi: out std_logic := '0'; -- TDI Jtag pin trst: out std_logic := '1'; -- TRST Jtag pin -- Clock and SM setting new_state: out std_logic_vector(3 downto 0); -- tap_sm new state cks: out std_logic_vector(2 downto 0) -- Clock divider ); end serializer; architecture rtl of serializer is signal count: integer range 0 to 8 := 0; signal state: integer range 0 to 15 := 0; signal rclk: integer range 0 to 1 := 0; signal sclk: integer range 0 to 1 := 0; signal instr: integer range 0 to 1 := 0; -- 0=Instruction, 1=Data, 2=Shift out, 3/4 shift in signal ssm: integer range 0 to 15 := 0; -- Shift and data state machine signal dir: std_logic := '1'; -- '0' = MSB, '1' = LSB signal rtms: std_logic := '0'; -- TMS state at last shift bit signal shift: std_logic_vector(7 downto 0); signal rbyte: std_logic_vector(7 downto 0); begin changestate: process(clk, rclk, rxf, txe, pwr, rst) begin if (rising_edge(clk)) then if rclk = 1 then rclk <= 0; else rclk <= 1; end if; -- st <= std_logic_vector(to_unsigned(state, st'length)); if wrk = '0' then case ssm is when 0 => tck <= '0'; tms <= '0'; tdi <= '0'; if rxf = '0' then -- Start byte read from FT245BM rd <= '0'; -- Send RD# to FT245BM ssm <= 1; -- Change to next state end if; when 1 => rbyte <= db; -- Read byte from FT245BM db <= "ZZZZZZZZ"; rd <= '1'; -- Select next byte from FT245BM ssm <= 2; -- Change state; when 2 => case instr is when 0 => -- Is an instruction byte case rbyte(3 downto 0) is when "0000" => -- rbyte(7 downto 4) have the new clock divisor cks <= rbyte(7 downto 5); -- Set clock divisor when "0001" => -- rbyte(7 downto 4) have then new state new_state <= rbyte(7 downto 4); ssm <= 3; -- Reset state machine when "0010" => -- Get current TAP state rbyte(3 downto 0) <= std_logic_vector(to_unsigned(state, rbyte(3 downto 0)'length)); rbyte(4) <= dir; ssm <= 5; when "0011" => -- Software reset TAP count <= to_integer(unsigned(rbyte(7 downto 4))); ssm <= 9; tms <= '1'; when "0100" => -- Hardware reset TAP count <= to_integer(unsigned(rbyte(7 downto 4)) - 1); ssm <= 8; when "0101" => -- Set MSB/LSB shift direction dir <= rbyte(4); -- Set shift direction sclk <= 0; ssm <= 0; -- Reset state machine when "0110" => -- Latch the next byte as shift data if state = 0 or state = 4 or state = 11 then count <= to_integer(unsigned(rbyte(7 downto 5))); rtms <= rbyte(4); -- TMS state at last shifted bit instr <= 1; -- Next is data to send sclk <= 0; ssm <= 0; -- Reset state machine end if; when others => ssm <= 0; -- Error, reset state machine end case; when 1 => -- There is a count bits to shift in/out -- st <= std_logic_vector(to_unsigned(count, st'length)); if sclk = 0 then tck <= '0'; if dir = '0' then tdi <= rbyte(7); rbyte(7 downto 1) <= rbyte(6 downto 0); else tdi <= rbyte(0); rbyte(6 downto 0) <= rbyte(7 downto 1); end if; sclk <= 1; if count = 0 then tms <= rtms; end if; else tck <= '1'; -- Read TDO if dir = '1' then shift(6 downto 0) <= shift(7 downto 1); shift(7) <= tdo; else shift(7 downto 1) <= shift(6 downto 0); shift(0) <= tdo; end if; if count > 0 then count <= count - 1; else ssm <= 5; instr <= 0; end if; sclk <= 0; end if; when others => end case; -- Delay for SM state start to work when 3 => ssm <= 4; when 4 => ssm <= 0; -- Write rbyte to data bus when 5 => tck <= '0'; tms <= '0'; tdi <= '0'; if txe = '0' then ssm <= 6; db <= shift; end if; when 6 => wr <= '0'; ssm <= 7; when 7 => wr <= '1'; ssm <= 0; db <= "ZZZZZZZZ"; if rtms = '1' then if state = 4 or state = 11 then state <= state + 1; end if; else if state = 0 then state <= state + 1; end if; end if; when 8 => if count = 0 then trst <= '1'; ssm <= 0; else trst <= '0'; count <= count - 1; end if; when 9 => if sclk = 0 then tck <= '1'; else tck <= '0'; if count > 0 then count <= count - 1; else tms <= '0'; ssm <= 0; end if; end if; when others => end case; end if; end if; end process changestate; end rtl;