------------------------------------------------------------------------------ -- user_logic.vhd - entity/architecture pair ------------------------------------------------------------------------------ -- -- *************************************************************************** -- ** Copyright (c) 1995-2008 Xilinx, Inc. All rights reserved. ** -- ** ** -- ** Xilinx, Inc. ** -- ** XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" ** -- ** AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND ** -- ** SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, ** -- ** OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, ** -- ** APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION ** -- ** THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, ** -- ** AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE ** -- ** FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY ** -- ** WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE ** -- ** IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR ** -- ** REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF ** -- ** INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ** -- ** FOR A PARTICULAR PURPOSE. ** -- ** ** -- *************************************************************************** -- ------------------------------------------------------------------------------ -- Filename: user_logic.vhd -- Version: 1.00.a -- Description: User logic. -- Date: Wed Apr 08 11:29:35 2009 (by Create and Import Peripheral Wizard) -- VHDL Standard: VHDL'93 ------------------------------------------------------------------------------ -- Naming Conventions: -- active low signals: "*_n" -- clock signals: "clk", "clk_div#", "clk_#x" -- reset signals: "rst", "rst_n" -- generics: "C_*" -- user defined types: "*_TYPE" -- state machine next state: "*_ns" -- state machine current state: "*_cs" -- combinatorial signals: "*_com" -- pipelined or register delay signals: "*_d#" -- counter signals: "*cnt*" -- clock enable signals: "*_ce" -- internal version of output port: "*_i" -- device pins: "*_pin" -- ports: "- Names begin with Uppercase" -- processes: "*_PROCESS" -- component instantiations: "I_<#|FUNC>" ------------------------------------------------------------------------------ -- DO NOT EDIT BELOW THIS LINE -------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; library proc_common_v2_00_a; use proc_common_v2_00_a.proc_common_pkg.all; use proc_common_v2_00_a.srl_fifo_f; -- DO NOT EDIT ABOVE THIS LINE -------------------- --USER libraries added here ------------------------------------------------------------------------------ -- Entity section ------------------------------------------------------------------------------ -- Definition of Generics: -- C_SLV_DWIDTH -- Slave interface data bus width -- C_MST_AWIDTH -- Master interface address bus width -- C_MST_DWIDTH -- Master interface data bus width -- C_NUM_REG -- Number of software accessible registers -- C_NUM_INTR -- Number of interrupt event -- -- Definition of Ports: -- Bus2IP_Clk -- Bus to IP clock -- Bus2IP_Reset -- Bus to IP reset -- Bus2IP_Data -- Bus to IP data bus -- Bus2IP_BE -- Bus to IP byte enables -- Bus2IP_RdCE -- Bus to IP read chip enable -- Bus2IP_WrCE -- Bus to IP write chip enable -- IP2Bus_Data -- IP to Bus data bus -- IP2Bus_RdAck -- IP to Bus read transfer acknowledgement -- IP2Bus_WrAck -- IP to Bus write transfer acknowledgement -- IP2Bus_Error -- IP to Bus error response -- IP2Bus_MstRd_Req -- IP to Bus master read request -- IP2Bus_MstWr_Req -- IP to Bus master write request -- IP2Bus_Mst_Addr -- IP to Bus master address bus -- IP2Bus_Mst_BE -- IP to Bus master byte enables -- IP2Bus_Mst_Lock -- IP to Bus master lock -- IP2Bus_Mst_Reset -- IP to Bus master reset -- Bus2IP_Mst_CmdAck -- Bus to IP master command acknowledgement -- Bus2IP_Mst_Cmplt -- Bus to IP master transfer completion -- Bus2IP_Mst_Error -- Bus to IP master error response -- Bus2IP_Mst_Rearbitrate -- Bus to IP master re-arbitrate -- Bus2IP_Mst_Cmd_Timeout -- Bus to IP master command timeout -- Bus2IP_MstRd_d -- Bus to IP master read data bus -- Bus2IP_MstRd_src_rdy_n -- Bus to IP master read source ready -- IP2Bus_MstWr_d -- IP to Bus master write data bus -- Bus2IP_MstWr_dst_rdy_n -- Bus to IP master write destination ready -- IP2Bus_IntrEvent -- IP to Bus interrupt event ------------------------------------------------------------------------------ entity user_logic is generic ( -- ADD USER GENERICS BELOW THIS LINE --------------- --USER generics added here -- ADD USER GENERICS ABOVE THIS LINE --------------- -- DO NOT EDIT BELOW THIS LINE --------------------- -- Bus protocol parameters, do not add to or delete C_SLV_DWIDTH : integer := 32; C_MST_AWIDTH : integer := 32; C_MST_DWIDTH : integer := 32; C_NUM_REG : integer := 7; C_NUM_INTR : integer := 1 -- DO NOT EDIT ABOVE THIS LINE --------------------- ); port ( -- ADD USER PORTS BELOW THIS LINE ------------------ --USER ports added here -- ADD USER PORTS ABOVE THIS LINE ------------------ -- DO NOT EDIT BELOW THIS LINE --------------------- -- Bus protocol ports, do not add to or delete Bus2IP_Clk : in std_logic; Bus2IP_Reset : in std_logic; Bus2IP_Data : in std_logic_vector(0 to C_SLV_DWIDTH-1); Bus2IP_BE : in std_logic_vector(0 to C_SLV_DWIDTH/8-1); Bus2IP_RdCE : in std_logic_vector(0 to C_NUM_REG-1); Bus2IP_WrCE : in std_logic_vector(0 to C_NUM_REG-1); IP2Bus_Data : out std_logic_vector(0 to C_SLV_DWIDTH-1); IP2Bus_RdAck : out std_logic; IP2Bus_WrAck : out std_logic; IP2Bus_Error : out std_logic; IP2Bus_MstRd_Req : out std_logic; IP2Bus_MstWr_Req : out std_logic; IP2Bus_Mst_Addr : out std_logic_vector(0 to C_MST_AWIDTH-1); IP2Bus_Mst_BE : out std_logic_vector(0 to C_MST_DWIDTH/8-1); IP2Bus_Mst_Lock : out std_logic; IP2Bus_Mst_Reset : out std_logic; Bus2IP_Mst_CmdAck : in std_logic; Bus2IP_Mst_Cmplt : in std_logic; Bus2IP_Mst_Error : in std_logic; Bus2IP_Mst_Rearbitrate : in std_logic; Bus2IP_Mst_Cmd_Timeout : in std_logic; Bus2IP_MstRd_d : in std_logic_vector(0 to C_MST_DWIDTH-1); Bus2IP_MstRd_src_rdy_n : in std_logic; IP2Bus_MstWr_d : out std_logic_vector(0 to C_MST_DWIDTH-1); Bus2IP_MstWr_dst_rdy_n : in std_logic; IP2Bus_IntrEvent : out std_logic_vector(0 to C_NUM_INTR-1) -- DO NOT EDIT ABOVE THIS LINE --------------------- ); attribute SIGIS : string; attribute SIGIS of Bus2IP_Clk : signal is "CLK"; attribute SIGIS of Bus2IP_Reset : signal is "RST"; attribute SIGIS of IP2Bus_Mst_Reset: signal is "RST"; end entity user_logic; ------------------------------------------------------------------------------ -- Architecture section ------------------------------------------------------------------------------ architecture IMP of user_logic is --USER signal declarations added here, as needed for user logic component DFT_CORE generic ( DFT_SLV_DWIDTH: integer := 32; DFT_MST_AWIDTH: integer := 32; DFT_MST_DWIDTH: integer := 32 ); port ( Clk: in std_logic; Reset: in std_logic; dft_busy : in std_logic; dft_go : out std_logic; dft_intern_req : out std_logic; dft_time_addr : in std_logic_vector(0 to DFT_SLV_DWIDTH-1); dft_real_addr : in std_logic_vector(0 to DFT_SLV_DWIDTH-1); dft_imag_addr : in std_logic_vector(0 to DFT_SLV_DWIDTH-1); dft_read_cmd : out std_logic; dft_write_cmd : out std_logic; dft_out_addr : out std_logic_vector(0 to DFT_MST_AWIDTH-1); dft_read_data : in std_logic_vector(0 to DFT_MST_DWIDTH-1); dft_write_data : out std_logic_vector(0 to DFT_MST_DWIDTH-1); dft_read_data_xfer : in std_logic; dft_write_data_xfer : in std_logic; dft_interrupt_done : out std_logic ); end component; ------------------------------------------ -- Signals for user logic slave model s/w accessible register example ------------------------------------------ signal slv_reg0 : std_logic_vector(0 to C_SLV_DWIDTH-1); signal slv_reg1 : std_logic_vector(0 to C_SLV_DWIDTH-1); signal slv_reg2 : std_logic_vector(0 to C_SLV_DWIDTH-1); signal slv_reg_write_sel : std_logic_vector(0 to 2); signal slv_reg_read_sel : std_logic_vector(0 to 2); signal slv_ip2bus_data : std_logic_vector(0 to C_SLV_DWIDTH-1); signal slv_read_ack : std_logic; signal slv_write_ack : std_logic; ------------------------------------------ -- Signals for user logic master model example ------------------------------------------ -- signals for master model control/status registers write/read signal mst_ip2bus_data : std_logic_vector(0 to C_SLV_DWIDTH-1); signal mst_reg_write_req : std_logic; signal mst_reg_read_req : std_logic; signal mst_reg_write_sel : std_logic_vector(0 to 3); signal mst_reg_read_sel : std_logic_vector(0 to 3); signal mst_write_ack : std_logic; signal mst_read_ack : std_logic; -- signals for master model control/status registers type BYTE_REG_TYPE is array(0 to 15) of std_logic_vector(0 to 7); signal mst_reg : BYTE_REG_TYPE; signal mst_byte_we : std_logic_vector(0 to 15); signal mst_cntl_rd_req : std_logic; signal mst_cntl_wr_req : std_logic; signal mst_cntl_bus_lock : std_logic; signal mst_cntl_burst : std_logic; signal mst_ip2bus_addr : std_logic_vector(0 to C_MST_AWIDTH-1); signal mst_xfer_length : std_logic_vector(0 to 11); signal mst_ip2bus_be : std_logic_vector(0 to 15); signal mst_go : std_logic; -- signals for master model command interface state machine type CMD_CNTL_SM_TYPE is (CMD_IDLE, CMD_RUN, CMD_WAIT_FOR_DATA, CMD_DONE); signal mst_cmd_sm_state : CMD_CNTL_SM_TYPE; signal mst_cmd_sm_set_done : std_logic; signal mst_cmd_sm_set_error : std_logic; signal mst_cmd_sm_set_timeout : std_logic; signal mst_cmd_sm_busy : std_logic; signal mst_cmd_sm_clr_go : std_logic; signal mst_cmd_sm_rd_req : std_logic; signal mst_cmd_sm_wr_req : std_logic; signal mst_cmd_sm_reset : std_logic; signal mst_cmd_sm_bus_lock : std_logic; signal mst_cmd_sm_ip2bus_addr : std_logic_vector(0 to C_MST_AWIDTH-1); signal mst_cmd_sm_ip2bus_be : std_logic_vector(0 to C_MST_DWIDTH/8-1); signal mst_fifo_valid_write_xfer : std_logic; signal mst_fifo_valid_read_xfer : std_logic; signal fifo_data_out : std_logic_vector(0 to C_MST_DWIDTH-1); signal dft_go : std_logic; signal dft_intern_req : std_logic; signal dft_read_cmd : std_logic; signal dft_write_cmd : std_logic; signal dft_out_addr : std_logic_vector(0 to C_MST_AWIDTH-1); signal dft_read_data : std_logic_vector(0 to C_MST_DWIDTH-1); signal dft_write_data : std_logic_vector(0 to C_MST_DWIDTH-1); signal dft_read_data_xfer : std_logic; signal dft_write_data_xfer : std_logic; signal dft_interrupt_done : std_logic; ------------------------------------------ -- Signals for user logic interrupt example ------------------------------------------ -- signal intr_counter : std_logic_vector(0 to C_NUM_INTR-1); begin --USER logic implementation added here DFT_CORE_INSTANCE: DFT_CORE generic map ( DFT_SLV_DWIDTH => C_SLV_DWIDTH, DFT_MST_AWIDTH => C_MST_AWIDTH, DFT_MST_DWIDTH => C_MST_DWIDTH ) port map ( Clk => Bus2IP_Clk, Reset => Bus2IP_Reset, dft_busy => mst_cmd_sm_busy, dft_go => dft_go, dft_intern_req => dft_intern_req, dft_time_addr => slv_reg0, dft_real_addr => slv_reg1, dft_imag_addr => slv_reg2, dft_read_cmd => dft_read_cmd, dft_write_cmd => dft_write_cmd, dft_out_addr => dft_out_addr, dft_read_data => dft_read_data, dft_write_data => dft_write_data, dft_read_data_xfer => dft_read_data_xfer, dft_write_data_xfer => dft_write_data_xfer, dft_interrupt_done => dft_interrupt_done ); ------------------------------------------ -- Example code to read/write user logic slave model s/w accessible registers -- -- Note: -- The example code presented here is to show you one way of reading/writing -- software accessible registers implemented in the user logic slave model. -- Each bit of the Bus2IP_WrCE/Bus2IP_RdCE signals is configured to correspond -- to one software accessible register by the top level template. For example, -- if you have four 32 bit software accessible registers in the user logic, -- you are basically operating on the following memory mapped registers: -- -- Bus2IP_WrCE/Bus2IP_RdCE Memory Mapped Register -- "1000" C_BASEADDR + 0x0 -- "0100" C_BASEADDR + 0x4 -- "0010" C_BASEADDR + 0x8 -- "0001" C_BASEADDR + 0xC -- ------------------------------------------ slv_reg_write_sel <= Bus2IP_WrCE(0 to 2); slv_reg_read_sel <= Bus2IP_RdCE(0 to 2); slv_write_ack <= Bus2IP_WrCE(0) or Bus2IP_WrCE(1) or Bus2IP_WrCE(2); slv_read_ack <= Bus2IP_RdCE(0) or Bus2IP_RdCE(1) or Bus2IP_RdCE(2); -- implement slave model software accessible register(s) SLAVE_REG_WRITE_PROC : process( Bus2IP_Clk ) is begin if Bus2IP_Clk'event and Bus2IP_Clk = '1' then if Bus2IP_Reset = '1' then slv_reg0 <= (others => '0'); slv_reg1 <= (others => '0'); slv_reg2 <= (others => '0'); else case slv_reg_write_sel is when "100" => for byte_index in 0 to (C_SLV_DWIDTH/8)-1 loop if ( Bus2IP_BE(byte_index) = '1' ) then slv_reg0(byte_index*8 to byte_index*8+7) <= Bus2IP_Data(byte_index*8 to byte_index*8+7); end if; end loop; when "010" => for byte_index in 0 to (C_SLV_DWIDTH/8)-1 loop if ( Bus2IP_BE(byte_index) = '1' ) then slv_reg1(byte_index*8 to byte_index*8+7) <= Bus2IP_Data(byte_index*8 to byte_index*8+7); end if; end loop; when "001" => for byte_index in 0 to (C_SLV_DWIDTH/8)-1 loop if ( Bus2IP_BE(byte_index) = '1' ) then slv_reg2(byte_index*8 to byte_index*8+7) <= Bus2IP_Data(byte_index*8 to byte_index*8+7); end if; end loop; when others => null; end case; end if; end if; end process SLAVE_REG_WRITE_PROC; -- implement slave model software accessible register(s) read mux SLAVE_REG_READ_PROC : process( slv_reg_read_sel, slv_reg0, slv_reg1, slv_reg2 ) is begin case slv_reg_read_sel is when "100" => slv_ip2bus_data <= slv_reg0; when "010" => slv_ip2bus_data <= slv_reg1; when "001" => slv_ip2bus_data <= slv_reg2; when others => slv_ip2bus_data <= (others => '0'); end case; end process SLAVE_REG_READ_PROC; ------------------------------------------ -- Example code to demonstrate user logic master model functionality -- -- Note: -- The example code presented here is to show you one way of stimulating -- the PLBv46 master interface under user control. It is provided for -- demonstration purposes only and allows the user to exercise the PLBv46 -- master interface during test and evaluation of the template. -- This user logic master model contains a 16-byte flattened register and -- the user is required to initialize the value to desire and then write to -- the model's 'Go' port to initiate the user logic master operation. -- -- Control Register (C_BASEADDR + OFFSET + 0x0): -- bit 0 - Rd (Read Request Control) -- bit 1 - Wr (Write Request Control) -- bit 2 - BL (Bus Lock Control) -- bit 3 - Brst (Burst Assertion Control) -- bit 4-7 - Spare (Spare Control Bits) -- Status Register (C_BASEADDR + OFFSET + 0x1): -- bit 0 - Done (Transfer Done Status) -- bit 1 - Busy (User Logic Master is Busy) -- bit 2 - Error (User Logic Master request got error response) -- bit 3 - Tmout (User Logic Master request is timeout) -- bit 2-7 - Spare (Spare Status Bits) -- Addrress Register (C_BASEADDR + OFFSET + 0x4): -- bit 0-31 - Target Address (This 32-bit value is used to populate the -- IP2Bus_Mst_Addr(0:31) address bus during a Read or Write -- user logic master operation) -- Byte Enable Register (C_BASEADDR + OFFSET + 0x8): -- bit 0-15 - Master BE (This 16-bit value is used to populate the -- IP2Bus_Mst_BE byte enable bus during a Read or Write user -- logic master operation for single data beat transfer) -- Length Register (C_BASEADDR + OFFSET + 0xC): -- bit 0-3 - Reserved -- bit 4-15 - Transfer Length (This 12-bit value is used to populate the -- IP2Bus_Mst_Length(0:11) transfer length bus which specifies -- the number of bytes (1 to 4096) to transfer during user logic -- master Read or Write fixed length burst operations) -- Go Register (C_BASEADDR + OFFSET + 0xF): -- bit 0-7 - Go Port (Write to this byte address initiates the user -- logic master transfer, data key value of 0x0A must be used) -- -- Note: OFFSET may be different depending on your address space configuration, -- by default it's either 0x0 or 0x100. Refer to IPIF address range array -- for actual value. -- -- Here's an example procedure in your software application to initiate a 4-byte -- write operation (single data beat) of this master model: -- 1. write 0x40 to the control register -- 2. write the target address to the address register -- 3. write valid byte lane value to the be register -- - note: this value must be aligned with ip2bus address -- 4. write 0x0004 to the length register -- 5. write 0x0a to the go register, this will start the master write operation -- ------------------------------------------ mst_reg_write_req <= Bus2IP_WrCE(3) or Bus2IP_WrCE(4) or Bus2IP_WrCE(5) or Bus2IP_WrCE(6); mst_reg_read_req <= Bus2IP_RdCE(3) or Bus2IP_RdCE(4) or Bus2IP_RdCE(5) or Bus2IP_RdCE(6); mst_reg_write_sel <= Bus2IP_WrCE(3 to 6); mst_reg_read_sel <= Bus2IP_RdCE(3 to 6); mst_write_ack <= mst_reg_write_req; mst_read_ack <= mst_reg_read_req; -- rip control bits from master model registers mst_cntl_rd_req <= mst_reg(0)(0); mst_cntl_wr_req <= mst_reg(0)(1); mst_cntl_bus_lock <= mst_reg(0)(2); mst_cntl_burst <= mst_reg(0)(3); mst_ip2bus_addr <= mst_reg(4) & mst_reg(5) & mst_reg(6) & mst_reg(7); mst_ip2bus_be <= mst_reg(8) & mst_reg(9); mst_xfer_length <= mst_reg(12)(4 to 7) & mst_reg(13); -- implement byte write enable for each byte slice of the master model registers MASTER_REG_BYTE_WR_EN : process( Bus2IP_BE, mst_reg_write_req, mst_reg_write_sel ) is constant BE_WIDTH : integer := C_SLV_DWIDTH/8; begin for byte_index in 0 to 15 loop mst_byte_we(byte_index) <= mst_reg_write_req and mst_reg_write_sel(byte_index/BE_WIDTH) and Bus2IP_BE(byte_index-(byte_index/BE_WIDTH)*BE_WIDTH); end loop; end process MASTER_REG_BYTE_WR_EN; -- implement master model registers MASTER_REG_WRITE_PROC : process( Bus2IP_Clk ) is constant BE_WIDTH : integer := C_SLV_DWIDTH/8; begin if ( Bus2IP_Clk'event and Bus2IP_Clk = '1' ) then if ( Bus2IP_Reset = '1' ) then mst_reg(0 to 14) <= (others => "00000000"); else -- If I want internal control from my module, then set dft_go to '1'. if ( dft_go = '1' ) then mst_reg(0)(0) <= dft_read_cmd; mst_reg(0)(1) <= dft_write_cmd; -- 'Done'/'error'/'timeout' from master control state machine mst_reg(1)(0) <= mst_cmd_sm_set_done or mst_reg(1)(0); -- status mst_reg(1)(1) <= mst_cmd_sm_busy; mst_reg(1)(2) <= mst_cmd_sm_set_error or mst_reg(1)(2); mst_reg(1)(3) <= mst_cmd_sm_set_timeout or mst_reg(1)(3); -- address into bytes 4-7 mst_reg(4) <= dft_out_addr(0 to 7); mst_reg(5) <= dft_out_addr(8 to 15); mst_reg(6) <= dft_out_addr(16 to 23); mst_reg(7) <= dft_out_addr(24 to 31); -- enables in bytes 8 and 9 -- set to FFFF mst_reg(8) <= X"FF"; mst_reg(9) <= X"FF"; -- len request -- 4 bytes. mst_reg(12) <= X"00"; mst_reg(13) <= X"04"; else -- control register (byte 0) if ( mst_byte_we(0) = '1' ) then mst_reg(0) <= Bus2IP_Data(0 to 7); end if; -- status register (byte 1) mst_reg(1)(1) <= mst_cmd_sm_busy; if ( mst_byte_we(1) = '1' ) then -- allows a clear of the 'Done'/'error'/'timeout' mst_reg(1)(0) <= Bus2IP_Data((1-(1/BE_WIDTH)*BE_WIDTH)*8); mst_reg(1)(2) <= Bus2IP_Data((1-(1/BE_WIDTH)*BE_WIDTH)*8+2); mst_reg(1)(3) <= Bus2IP_Data((1-(1/BE_WIDTH)*BE_WIDTH)*8+3); else -- 'Done'/'error'/'timeout' from master control state machine mst_reg(1)(0) <= mst_cmd_sm_set_done or mst_reg(1)(0); mst_reg(1)(2) <= mst_cmd_sm_set_error or mst_reg(1)(2); mst_reg(1)(3) <= mst_cmd_sm_set_timeout or mst_reg(1)(3); end if; -- byte 2 and 3 are reserved, address register (byte 4 to 7), 'be' register (byte 8 to 9) -- length register (byte 12 to 13), byte 10, 11 and 14 are reserved for byte_index in 4 to 14 loop if ( mst_byte_we(byte_index) = '1' ) then mst_reg(byte_index) <= Bus2IP_Data( (byte_index-(byte_index/BE_WIDTH)*BE_WIDTH)*8 to (byte_index-(byte_index/BE_WIDTH)*BE_WIDTH)*8+7); end if; end loop; end if; end if; end if; end process MASTER_REG_WRITE_PROC; -- implement master model write only 'go' port MASTER_WRITE_GO_PORT : process( Bus2IP_Clk ) is constant GO_DATA_KEY : std_logic_vector(0 to 7) := X"0A"; constant GO_BYTE_LANE : integer := 15; constant BE_WIDTH : integer := C_SLV_DWIDTH/8; begin if ( Bus2IP_Clk'event and Bus2IP_Clk = '1' ) then if ( Bus2IP_Reset = '1' or mst_cmd_sm_clr_go = '1' ) then mst_go <= '0'; -- I check mst_cmd_sm_busy in my module. elsif ( dft_go = '1' ) then mst_go <= '1'; elsif ( mst_cmd_sm_busy = '0' and mst_byte_we(GO_BYTE_LANE) = '1' and Bus2IP_Data((GO_BYTE_LANE-(GO_BYTE_LANE/BE_WIDTH)*BE_WIDTH)*8 to (GO_BYTE_LANE-(GO_BYTE_LANE/BE_WIDTH)*BE_WIDTH)*8+7) = GO_DATA_KEY ) then mst_go <= '1'; else null; end if; end if; end process MASTER_WRITE_GO_PORT; -- implement master model register read mux MASTER_REG_READ_PROC : process( mst_reg_read_sel, mst_reg ) is constant BE_WIDTH : integer := C_SLV_DWIDTH/8; begin case mst_reg_read_sel is when "1000" => for byte_index in 0 to BE_WIDTH-1 loop mst_ip2bus_data(byte_index*8 to byte_index*8+7) <= mst_reg(byte_index); end loop; when "0100" => for byte_index in 0 to BE_WIDTH-1 loop mst_ip2bus_data(byte_index*8 to byte_index*8+7) <= mst_reg(BE_WIDTH+byte_index); end loop; when "0010" => for byte_index in 0 to BE_WIDTH-1 loop mst_ip2bus_data(byte_index*8 to byte_index*8+7) <= mst_reg(BE_WIDTH*2+byte_index); end loop; when "0001" => for byte_index in 0 to BE_WIDTH-1 loop if ( byte_index = BE_WIDTH-1 ) then -- go port is not readable mst_ip2bus_data(byte_index*8 to byte_index*8+7) <= (others => '0'); else mst_ip2bus_data(byte_index*8 to byte_index*8+7) <= mst_reg(BE_WIDTH*3+byte_index); end if; end loop; when others => mst_ip2bus_data <= (others => '0'); end case; end process MASTER_REG_READ_PROC; -- user logic master command interface assignments IP2Bus_MstRd_Req <= mst_cmd_sm_rd_req; IP2Bus_MstWr_Req <= mst_cmd_sm_wr_req; IP2Bus_Mst_Addr <= mst_cmd_sm_ip2bus_addr; IP2Bus_Mst_BE <= mst_cmd_sm_ip2bus_be; IP2Bus_Mst_Lock <= mst_cmd_sm_bus_lock; IP2Bus_Mst_Reset <= mst_cmd_sm_reset; --implement master command interface state machine MASTER_CMD_SM_PROC : process( Bus2IP_Clk ) is begin if ( Bus2IP_Clk'event and Bus2IP_Clk = '1' ) then if ( Bus2IP_Reset = '1' ) then -- reset condition mst_cmd_sm_state <= CMD_IDLE; mst_cmd_sm_clr_go <= '0'; mst_cmd_sm_rd_req <= '0'; mst_cmd_sm_wr_req <= '0'; mst_cmd_sm_bus_lock <= '0'; mst_cmd_sm_reset <= '0'; mst_cmd_sm_ip2bus_addr <= (others => '0'); mst_cmd_sm_ip2bus_be <= (others => '0'); mst_cmd_sm_set_done <= '0'; mst_cmd_sm_set_error <= '0'; mst_cmd_sm_set_timeout <= '0'; mst_cmd_sm_busy <= '0'; else -- default condition mst_cmd_sm_clr_go <= '0'; mst_cmd_sm_rd_req <= '0'; mst_cmd_sm_wr_req <= '0'; mst_cmd_sm_bus_lock <= '0'; mst_cmd_sm_reset <= '0'; mst_cmd_sm_ip2bus_addr <= (others => '0'); mst_cmd_sm_ip2bus_be <= (others => '0'); mst_cmd_sm_set_done <= '0'; mst_cmd_sm_set_error <= '0'; mst_cmd_sm_set_timeout <= '0'; mst_cmd_sm_busy <= '1'; -- state transition case mst_cmd_sm_state is when CMD_IDLE => if ( mst_go = '1' ) then mst_cmd_sm_state <= CMD_RUN; mst_cmd_sm_clr_go <= '1'; else mst_cmd_sm_state <= CMD_IDLE; mst_cmd_sm_busy <= '0'; end if; when CMD_RUN => if ( Bus2IP_Mst_CmdAck = '1' and Bus2IP_Mst_Cmplt = '0' ) then mst_cmd_sm_state <= CMD_WAIT_FOR_DATA; elsif ( Bus2IP_Mst_Cmplt = '1' ) then mst_cmd_sm_state <= CMD_DONE; -- PLB address phase timeout if ( Bus2IP_Mst_Cmd_Timeout = '1' ) then mst_cmd_sm_set_error <= '1'; mst_cmd_sm_set_timeout <= '1'; -- PLB data transfer error elsif ( Bus2IP_Mst_Error = '1' ) then mst_cmd_sm_set_error <= '1'; end if; else mst_cmd_sm_state <= CMD_RUN; mst_cmd_sm_rd_req <= mst_cntl_rd_req; mst_cmd_sm_wr_req <= mst_cntl_wr_req; mst_cmd_sm_ip2bus_addr <= mst_ip2bus_addr; mst_cmd_sm_ip2bus_be <= mst_ip2bus_be(16-C_MST_DWIDTH/8 to 15); mst_cmd_sm_bus_lock <= mst_cntl_bus_lock; end if; when CMD_WAIT_FOR_DATA => if ( Bus2IP_Mst_Cmplt = '1' ) then mst_cmd_sm_state <= CMD_DONE; else mst_cmd_sm_state <= CMD_WAIT_FOR_DATA; end if; when CMD_DONE => mst_cmd_sm_state <= CMD_IDLE; mst_cmd_sm_set_done <= '1'; mst_cmd_sm_busy <= '0'; when others => mst_cmd_sm_state <= CMD_IDLE; mst_cmd_sm_busy <= '0'; end case; end if; end if; end process MASTER_CMD_SM_PROC; dft_read_data_xfer <= not(Bus2IP_MstRd_src_rdy_n); dft_write_data_xfer <= not(Bus2IP_MstWr_dst_rdy_n); dft_read_data <= Bus2IP_MstRd_d; -- Disable fifo if internal request underway. DATA_SELECT_PROC : process( dft_intern_req, dft_write_data, Bus2IP_MstRd_src_rdy_n, Bus2IP_MstWr_dst_rdy_n, fifo_data_out ) is begin -- If the output bus is to be driven by the dft engine, then dft_intern_req is 1. -- Setting the FIFO control bits to 1 DISables the FIFO. if ( dft_intern_req = '1' ) then mst_fifo_valid_write_xfer <= '1'; mst_fifo_valid_read_xfer <= '1'; IP2Bus_MstWr_d <= dft_write_data; else -- local srl fifo for data storage mst_fifo_valid_write_xfer <= not(Bus2IP_MstRd_src_rdy_n); mst_fifo_valid_read_xfer <= not(Bus2IP_MstWr_dst_rdy_n); IP2Bus_MstWr_d <= fifo_data_out; end if; end process; DATA_CAPTURE_FIFO_I : entity proc_common_v2_00_a.srl_fifo_f generic map ( C_DWIDTH => C_MST_DWIDTH, C_DEPTH => 16 ) port map ( Clk => Bus2IP_Clk, Reset => Bus2IP_Reset, FIFO_Write => mst_fifo_valid_write_xfer, Data_In => Bus2IP_MstRd_d, FIFO_Read => mst_fifo_valid_read_xfer, Data_Out => fifo_data_out, FIFO_Full => open, FIFO_Empty => open, Addr => open ); ------------------------------------------ -- Example code to generate user logic interrupts -- -- Note: -- The example code presented here is to show you one way of generating -- interrupts from the user logic. This code snippet infers a counter -- and generate the interrupts whenever the counter rollover (the counter -- will rollover ~21 sec @50Mhz). ------------------------------------------ -- INTR_PROC : process( Bus2IP_Clk ) is -- constant COUNT_SIZE : integer := 30; -- constant ALL_ONES : std_logic_vector(0 to COUNT_SIZE-1) := (others => '1'); -- variable counter : std_logic_vector(0 to COUNT_SIZE-1); -- begin -- if ( Bus2IP_Clk'event and Bus2IP_Clk = '1' ) then -- if ( Bus2IP_Reset = '1' ) then -- counter := (others => '0'); -- intr_counter <= (others => '0'); -- else -- counter := counter + 1; -- if ( counter = ALL_ONES ) then -- intr_counter <= (others => '1'); -- else -- intr_counter <= (others => '0'); -- end if; -- end if; -- end if; -- end process INTR_PROC; -- IP2Bus_IntrEvent <= intr_counter; IP2Bus_IntrEvent(0) <= dft_interrupt_done; ------------------------------------------ -- Example code to drive IP to Bus signals ------------------------------------------ IP2Bus_Data <= slv_ip2bus_data when slv_read_ack = '1' else mst_ip2bus_data when mst_read_ack = '1' else (others => '0'); IP2Bus_WrAck <= slv_write_ack or mst_write_ack; IP2Bus_RdAck <= slv_read_ack or mst_read_ack; IP2Bus_Error <= '0'; end IMP;