📄 opb_spin_lock_if.vhd
字号:
library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;library Unisim;use Unisim.all;library Common_v1_00_a;use Common_v1_00_a.all;use Common_v1_00_a.Common_Types.all;use Common_v1_00_a.pselect;entity OPB_SPIN_LOCK_IF is generic ( C_OPB_AWIDTH : integer := 32; C_OPB_DWIDTH : integer := 32; C_BASEADDR : std_logic_vector(0 to 31) := X"0000_0000"; C_HIGHADDR : std_logic_vector(0 to 31) := X"FFFF_FFFF"); port ( -- OPB Slave Interface OPB_Clk : in std_logic; OPB_Rst : in std_logic; OPB_ABus : in std_logic_vector(0 to C_OPB_AWIDTH - 1); OPB_BE : in std_logic_vector(0 to C_OPB_DWIDTH/8 - 1); OPB_DBus : in std_logic_vector(0 to C_OPB_DWIDTH - 1); OPB_RNW : in std_logic; OPB_select : in std_logic; OPB_seqAddr : in std_logic; SpinLockIf_DBus : out std_logic_vector(0 to C_OPB_DWIDTH - 1); SpinLockIf_errAck : out std_logic; SpinLockIf_retry : out std_logic; SpinLockIf_toutSup : out std_logic; SpinLockIf_xferAck : out std_logic; -- SPIN LOCK Interface-- SpinLock_RNW : out std_logic; SpinLock_Tsk0_RNW : out std_logic; SpinLock_Tsk1_RNW : out std_logic; SpinLock_Tsk2_RNW : out std_logic; SpinLock_Tsk3_RNW : out std_logic; SpinLock_Obj0_RNW : out std_logic; SpinLock_Obj1_RNW : out std_logic; SpinLock_Obj2_RNW : out std_logic; SpinLock_Obj3_RNW : out std_logic; SpinLock_Tsk0_Ack : in std_logic; SpinLock_Tsk1_Ack : in std_logic; SpinLock_Tsk2_Ack : in std_logic; SpinLock_Tsk3_Ack : in std_logic; SpinLock_Obj0_Ack : in std_logic; SpinLock_Obj1_Ack : in std_logic; SpinLock_Obj2_Ack : in std_logic; SpinLock_Obj3_Ack : in std_logic; SpinLock_Tsk0_TestSetBit : in std_logic; SpinLock_Tsk1_TestSetBit : in std_logic; SpinLock_Tsk2_TestSetBit : in std_logic; SpinLock_Tsk3_TestSetBit : in std_logic; SpinLock_Obj0_TestSetBit : in std_logic; SpinLock_Obj1_TestSetBit : in std_logic; SpinLock_Obj2_TestSetBit : in std_logic; SpinLock_Obj3_TestSetBit : in std_logic; SpinLock_CE0Tsk : out std_logic; SpinLock_CE0Obj : out std_logic; SpinLock_CE1Tsk : out std_logic; SpinLock_CE1Obj : out std_logic; SpinLock_CE2Tsk : out std_logic; SpinLock_CE2Obj : out std_logic; SpinLock_CE3Tsk : out std_logic; SpinLock_CE3Obj : out std_logic);end OPB_SPIN_LOCK_IF;architecture RTL of OPB_SPIN_LOCK_IF is component pselect generic ( C_AB : integer; C_AW : integer; C_BAR : std_logic_vector); port ( A : in std_logic_vector(0 to C_AW - 1); AValid : in std_logic; PS : out std_logic); end component; function GET_AWIDTH ( BASEADDR, HIGHADDR : std_logic_vector(0 to C_OPB_AWIDTH - 1)) return integer is variable tmp_awidth : std_logic_vector(0 to C_OPB_AWIDTH - 1); begin -- GET_AWIDTH tmp_awidth := BASEADDR xor HIGHADDR; for I in 0 to C_OPB_AWIDTH - 1 loop if (tmp_awidth(I) = '1') then return (I); end if; end loop; -- I return C_OPB_AWIDTH - 1; end GET_AWIDTH; constant C_AB : integer := GET_AWIDTH( C_BASEADDR, C_HIGHADDR ); --Register MAP constant TSK_ADDR0 : std_logic_vector(0 to 2) := "000"; --RW constant OBJ_ADDR0 : std_logic_vector(0 to 2) := "001"; --RW constant TSK_ADDR1 : std_logic_vector(0 to 2) := "010"; --RW constant OBJ_ADDR1 : std_logic_vector(0 to 2) := "011"; --RW constant TSK_ADDR2 : std_logic_vector(0 to 2) := "100"; --RW constant OBJ_ADDR2 : std_logic_vector(0 to 2) := "101"; --RW constant TSK_ADDR3 : std_logic_vector(0 to 2) := "110"; --RW constant OBJ_ADDR3 : std_logic_vector(0 to 2) := "111"; --RW constant TSK0 : integer := 0; constant OBJ0 : integer := 1; constant TSK1 : integer := 2; constant OBJ1 : integer := 3; constant TSK2 : integer := 4; constant OBJ2 : integer := 5; constant TSK3 : integer := 6; constant OBJ3 : integer := 7; signal TSK_REG0 : std_logic_vector(0 to 31); signal OBJ_REG0 : std_logic_vector(0 to 31); signal TSK_REG1 : std_logic_vector(0 to 31); signal OBJ_REG1 : std_logic_vector(0 to 31); signal TSK_REG2 : std_logic_vector(0 to 31); signal OBJ_REG2 : std_logic_vector(0 to 31); signal TSK_REG3 : std_logic_vector(0 to 31); signal OBJ_REG3 : std_logic_vector(0 to 31); constant LOCKBIT : integer := 31; signal LOCKED : std_logic; signal SEL : std_logic_vector(0 to 7); --STATE Machine type state_type is (IDLE, ACQUIRE_LOCK, RELEASE_LOCK); signal CURRENT_STATE : state_type; signal NEXT_STATE : state_type; --Signal signal s_select : std_logic; signal xfer_ack : std_logic; signal i_xfer_ack : std_logic; signal SpinLock_TestSetBit : std_logic; signal SpinLock_Ack : std_logic; begin -- RTL pselect_I : pselect generic map ( C_AB => C_AB, C_AW => C_OPB_AWIDTH, C_BAR => C_BASEADDR) port map ( A => OPB_ABus, AValid => OPB_select, PS => s_select); --Generate Selector Signal process (OPB_Rst, OPB_ABus, s_select) begin -- process if (OPB_Rst = '1') then SEL <= (others => '0'); elsif (s_select = '1') then case OPB_ABus(27 to 29) is when TSK_ADDR0 => SEL <= conv_std_logic_vector(2**(7-TSK0), 8); when OBJ_ADDR0 => SEL <= conv_std_logic_vector(2**(7-OBJ0), 8); when TSK_ADDR1 => SEL <= conv_std_logic_vector(2**(7-TSK1), 8); when OBJ_ADDR1 => SEL <= conv_std_logic_vector(2**(7-OBJ1), 8); when TSK_ADDR2 => SEL <= conv_std_logic_vector(2**(7-TSK2), 8); when OBJ_ADDR2 => SEL <= conv_std_logic_vector(2**(7-OBJ2), 8); when TSK_ADDR3 => SEL <= conv_std_logic_vector(2**(7-TSK3), 8); when OBJ_ADDR3 => SEL <= conv_std_logic_vector(2**(7-OBJ3), 8); when others => SEL <= (others => '0'); end case; else SEL <= (others => '0'); end if; end process; -- SpinLock_TestSetBit SpinLock_TestSetBit <= (SpinLock_Tsk0_TestSetBit and SEL(TSK0)) or (SpinLock_Tsk1_TestSetBit and SEL(TSK1)) or (SpinLock_Tsk2_TestSetBit and SEL(TSK2)) or (SpinLock_Tsk3_TestSetBit and SEL(TSK3)) or (SpinLock_Obj0_TestSetBit and SEL(OBJ0)) or (SpinLock_Obj1_TestSetBit and SEL(OBJ1)) or (SpinLock_Obj2_TestSetBit and SEL(OBJ2)) or (SpinLock_Obj3_TestSetBit and SEL(OBJ3)); --SpinLock_Ack SpinLock_Ack <= (SpinLock_Tsk0_Ack and SEL(TSK0)) or (SpinLock_Tsk1_Ack and SEL(TSK1)) or (SpinLock_Tsk2_Ack and SEL(TSK2)) or (SpinLock_Tsk3_Ack and SEL(TSK3)) or (SpinLock_Obj0_Ack and SEL(OBJ0)) or (SpinLock_Obj1_Ack and SEL(OBJ1)) or (SpinLock_Obj2_Ack and SEL(OBJ2)) or (SpinLock_Obj3_Ack and SEL(OBJ3)); --Generate LOCKED process (OPB_Rst, OPB_ABus, s_select, TSK_REG0, TSK_REG1, TSK_REG2, TSK_REG3, OBJ_REG0, OBJ_REG1, OBJ_REG2, OBJ_REG3) begin -- process if (OPB_Rst = '1') then LOCKED <= '0'; else case OPB_ABus(27 to 29) is when TSK_ADDR0 => LOCKED <= TSK_REG0(LOCKBIT) and s_select; when OBJ_ADDR0 => LOCKED <= OBJ_REG0(LOCKBIT) and s_select; when TSK_ADDR1 => LOCKED <= TSK_REG1(LOCKBIT) and s_select; when OBJ_ADDR1 => LOCKED <= OBJ_REG1(LOCKBIT) and s_select; when TSK_ADDR2 => LOCKED <= TSK_REG2(LOCKBIT) and s_select; when OBJ_ADDR2 => LOCKED <= OBJ_REG2(LOCKBIT) and s_select; when TSK_ADDR3 => LOCKED <= TSK_REG3(LOCKBIT) and s_select; when OBJ_ADDR3 => LOCKED <= OBJ_REG3(LOCKBIT) and s_select; when others => LOCKED <= 'X'; end case; end if; end process; --State Machine Update process (OPB_Clk, OPB_Rst) begin -- process if OPB_Rst = '1' then -- asynchronous reset (active low) CURRENT_STATE <= IDLE; elsif OPB_Clk'event and OPB_Clk = '1' then -- rising clock edge CURRENT_STATE <= NEXT_STATE; end if; end process; --Main State Machine process (OPB_Clk, OPB_Rst) begin -- process if OPB_Rst = '1' then -- asynchronous reset (active low) NEXT_STATE <= IDLE; elsif OPB_Clk'event and OPB_Clk = '1' then -- rising clock edge case CURRENT_STATE is when IDLE => if (s_select = '1' and OPB_RNW = '1' and LOCKED = '0') then NEXT_STATE <= ACQUIRE_LOCK;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -