Files
b210-k7-fpga/lib/vivado_ipi/axi_bitq/axi_bitq.vhd
T
Max Köhler 42d17bd090 fpga: lib: add generic to disable bitq engine tri-stating
Original-commit: b067b2af7924aa8577a8619f97d54122e0b71daf
2020-09-16 14:24:16 -05:00

227 lines
6.8 KiB
VHDL

--
-- Copyright 2018 Ettus Research, A National Instruments Company
--
-- SPDX-License-Identifier: LGPL-3.0
--
-- Module: axi_bitq
-- Description: Simple IP to shift bits in/out (primarily for JTAG)
-- axi_bitq is the processor interface to the bitq_fsm module
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.bitq_fsm;
entity axi_bitq is
port (
bit_clk : inout std_logic;
bit_in : in std_logic;
bit_out : inout std_logic;
bit_stb : inout std_logic;
S_AXI_ACLK : in std_logic;
S_AXI_ARESETN : in std_logic;
S_AXI_AWADDR : in std_logic_vector(3 downto 0);
S_AXI_AWVALID : in std_logic;
S_AXI_AWREADY : out std_logic;
S_AXI_WDATA : in std_logic_vector(31 downto 0);
S_AXI_WSTRB : in std_logic_vector(3 downto 0);
S_AXI_WVALID : in std_logic;
S_AXI_WREADY : out std_logic;
S_AXI_BRESP : out std_logic_vector(1 downto 0);
S_AXI_BVALID : out std_logic;
S_AXI_BREADY : in std_logic;
S_AXI_ARADDR : in std_logic_vector(3 downto 0);
S_AXI_ARVALID : in std_logic;
S_AXI_ARREADY : out std_logic;
S_AXI_RDATA : out std_logic_vector(31 downto 0);
S_AXI_RRESP : out std_logic_vector(1 downto 0);
S_AXI_RVALID : out std_logic;
S_AXI_RREADY : in std_logic
);
end axi_bitq;
architecture arch of axi_bitq is
signal read_token : std_logic;
signal write_addr : std_logic_vector(3 downto 0);
signal write_strb : std_logic_vector(3 downto 0);
signal write_addr_token : std_logic;
signal write_data : std_logic_vector(31 downto 0);
signal write_data_token : std_logic;
signal wr_data : std_logic_vector(31 downto 0);
signal stb_data : std_logic_vector(31 downto 0);
signal rd_data : std_logic_vector(31 downto 0);
signal prescalar : std_logic_vector(7 downto 0);
signal len : std_logic_vector(4 downto 0);
signal ready : std_logic;
signal start : std_logic;
signal bitq_rstn : std_logic;
signal bitq_soft_rst : std_logic;
begin
S_AXI_ARREADY <= not read_token;
S_AXI_RVALID <= read_token;
S_AXI_RRESP <= "00";
S_AXI_AWREADY <= not write_addr_token;
S_AXI_WREADY <= not write_data_token;
S_AXI_BVALID <= write_addr_token and write_data_token;
S_AXI_BRESP <= "00";
--Register reads
read_proc : process (S_AXI_ACLK)
variable read_addr : std_logic_vector(S_AXI_ARADDR'left downto S_AXI_ARADDR'right+2);
begin
if rising_edge(S_AXI_ACLK) then
read_addr := S_AXI_ARADDR(S_AXI_ARADDR'left downto S_AXI_ARADDR'right+2);
if (S_AXI_ARESETN = '0') then
read_token <= '0';
elsif (S_AXI_ARVALID = '1') and (read_token = '0') then
read_token <= '1';
elsif (S_AXI_RREADY = '1') and (read_token = '1') then
read_token <= '0';
end if;
if (S_AXI_ARVALID = '1') and (read_token = '0') then
S_AXI_RDATA <= (others => '0');
case read_addr is
when "00" =>
S_AXI_RDATA(31 downto 0) <= wr_data;
when "01" =>
S_AXI_RDATA(31 downto 0) <= stb_data;
when "10" =>
S_AXI_RDATA(7 downto 0) <= prescalar;
S_AXI_RDATA(12 downto 8) <= len;
S_AXI_RDATA(31) <= ready;
when "11" =>
S_AXI_RDATA(31 downto 0) <= rd_data;
when others =>
null;
end case;
end if;
end if;
end process read_proc;
write_proc : process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if (S_AXI_ARESETN = '0') then
write_addr_token <= '0';
write_data_token <= '0';
write_strb <= (others => '0');
else
if (S_AXI_AWVALID = '1') and (write_addr_token = '0') then
write_addr_token <= '1';
elsif (S_AXI_BREADY = '1') and (write_addr_token = '1') and (write_data_token = '1') then
write_addr_token <= '0';
end if;
if (S_AXI_WVALID = '1') and (write_data_token = '0') then
write_data_token <= '1';
elsif (S_AXI_BREADY = '1') and (write_addr_token = '1') and (write_data_token = '1') then
write_data_token <= '0';
end if;
end if;
if (S_AXI_AWVALID = '1') and (write_addr_token = '0') then
write_addr <= S_AXI_AWADDR;
end if;
if (S_AXI_WVALID = '1') and (write_data_token = '0') then
write_data <= S_AXI_WDATA;
write_strb <= S_AXI_WSTRB;
end if;
end if;
end process write_proc;
write_reg : process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
bitq_soft_rst <= '0';
start <= '0';
if (S_AXI_ARESETN = '0') or (bitq_soft_rst = '1') then
bitq_soft_rst <= '0';
start <= '0';
elsif (write_addr_token = '1') and (write_data_token = '1') then
case write_addr(write_addr'left downto 2) is
when "00" =>
if (write_strb(0) = '1') and (ready = '1') then
wr_data(7 downto 0) <= write_data(7 downto 0);
end if;
if (write_strb(1) = '1') and (ready = '1') then
wr_data(15 downto 8) <= write_data(15 downto 8);
end if;
if (write_strb(2) = '1') and (ready = '1') then
wr_data(23 downto 16) <= write_data(23 downto 16);
end if;
if (write_strb(3) = '1') and (ready = '1') then
wr_data(31 downto 24) <= write_data(31 downto 24);
end if;
when "01" =>
if (write_strb(0) = '1') and (ready = '1') then
stb_data(7 downto 0) <= write_data(7 downto 0);
end if;
if (write_strb(1) = '1') and (ready = '1') then
stb_data(15 downto 8) <= write_data(15 downto 8);
end if;
if (write_strb(2) = '1') and (ready = '1') then
stb_data(23 downto 16) <= write_data(23 downto 16);
end if;
if (write_strb(3) = '1') and (ready = '1') then
stb_data(31 downto 24) <= write_data(31 downto 24);
end if;
when "10" =>
if (write_strb(0) = '1') and (ready = '1') then
prescalar <= write_data(7 downto 0);
end if;
if (write_strb(1) = '1') and (ready = '1') then
len <= write_data(12 downto 8);
if (write_strb(3) = '0') or (write_data(31) = '0') then
start <= '1';
end if;
end if;
if (write_strb(3) = '1') then
bitq_soft_rst <= write_data(31);
end if;
when "11" => --Read only register
null;
when others =>
null;
end case;
end if;
end if;
end process write_reg;
bitq_rstn <= '0' when (S_AXI_ARESETN = '0') or (bitq_soft_rst = '1') else '1';
bitq_ctrl : entity bitq_fsm
generic map (
IDLE_VALUE => 'Z'
)
port map (
clk => S_AXI_ACLK,
rstn => S_AXI_ARESETN,
prescalar => prescalar,
bit_clk => bit_clk,
bit_in => bit_in,
bit_out => bit_out,
bit_stb => bit_stb,
start => start,
len => len,
ready => ready,
wr_data => wr_data,
stb_data => stb_data,
rd_data => rd_data
);
end arch;