146 lines
5.5 KiB
VHDL
146 lines
5.5 KiB
VHDL
ARCHITECTURE test OF ahbLite_tester IS
|
|
-- reset and clock
|
|
constant clockPeriod: time := (1.0/clockFrequency) * 1 sec;
|
|
signal clock_int: std_uLogic := '1';
|
|
-- register access
|
|
signal registerAddress: natural;
|
|
signal registerData: integer;
|
|
signal registerWrite: std_uLogic;
|
|
signal registerRead: std_uLogic;
|
|
-- AHB lite registers
|
|
signal addressReg: unsigned(hAddr'range);
|
|
signal writeReg: std_uLogic;
|
|
signal selPeriph1Reg: std_uLogic;
|
|
signal selPeriph2Reg: std_uLogic;
|
|
signal hSel: std_uLogic;
|
|
constant registerNb: positive := 2*periph2BaseAddress;
|
|
subtype registerType is std_uLogic_vector(hWdata'range);
|
|
type registerArrayType is array (registerNb-1 downto 0) of registerType;
|
|
signal registerArray: registerArrayType;
|
|
|
|
BEGIN
|
|
------------------------------------------------------------------------------
|
|
-- reset and clock
|
|
reset <= '1', '0' after 4*clockPeriod;
|
|
|
|
clock_int <= not clock_int after clockPeriod/2;
|
|
clock <= transport clock_int after clockPeriod*9.0/10.0;
|
|
|
|
|
|
------------------------------------------------------------------------------
|
|
-- test sequence
|
|
testSequence: process
|
|
begin
|
|
registerAddress <= 0;
|
|
registerData <= 0;
|
|
registerWrite <= '0';
|
|
registerRead <= '0';
|
|
wait for 100 ns;
|
|
-- write periph1 register 0
|
|
registerAddress <= 0;
|
|
registerData <= 1;
|
|
registerWrite <= '1', '0' after clockPeriod;
|
|
wait for 8*clockPeriod;
|
|
-- write periph1 register 1
|
|
registerAddress <= 1;
|
|
registerData <= 2;
|
|
registerWrite <= '1', '0' after clockPeriod;
|
|
wait for 8*clockPeriod;
|
|
-- write periph2 register 0
|
|
registerAddress <= periph2BaseAddress;
|
|
registerData <= periph2BaseAddress + 1;
|
|
registerWrite <= '1', '0' after clockPeriod;
|
|
wait for 2*clockPeriod;
|
|
-- write periph2 register 1
|
|
registerAddress <= periph2BaseAddress + 1;
|
|
registerData <= periph2BaseAddress + 2;
|
|
registerWrite <= '1', '0' after clockPeriod;
|
|
wait for 8*clockPeriod;
|
|
-- read periph1 register 0
|
|
registerAddress <= 0;
|
|
registerRead <= '1', '0' after clockPeriod;
|
|
wait for 8*clockPeriod;
|
|
-- read periph2 register 0
|
|
registerAddress <= periph2BaseAddress;
|
|
registerRead <= '1', '0' after clockPeriod;
|
|
wait for 8*clockPeriod;
|
|
|
|
wait;
|
|
end process testSequence;
|
|
|
|
--============================================================================
|
|
-- microprocessor bus access
|
|
busAccess: process
|
|
variable writeAccess: boolean;
|
|
begin
|
|
upAddress <= (others => '-');
|
|
upDataOut <= (others => '-');
|
|
upReadStrobe <= '0';
|
|
upWriteStrobe <= '0';
|
|
-- wait for transaction
|
|
wait on registerWrite, registerRead;
|
|
if not(hReset_n) = '0' then
|
|
writeAccess := false;
|
|
if rising_edge(registerWrite) then
|
|
writeAccess := true;
|
|
end if;
|
|
-- single-cycle bus access
|
|
wait until rising_edge(clock_int);
|
|
upAddress <= to_unsigned(registerAddress, hAddr'length);
|
|
if writeAccess then
|
|
upWriteStrobe <= '1';
|
|
upDataOut <= std_uLogic_vector(to_signed(registerData, upDataOut'length));
|
|
else
|
|
upReadStrobe <= '1';
|
|
end if;
|
|
wait until rising_edge(clock_int);
|
|
end if;
|
|
end process;
|
|
|
|
--============================================================================
|
|
-- AHB bus access
|
|
hSel <= hSelPeriph1 or hSelPeriph2;
|
|
-- address and controls
|
|
storeControls: process(hReset_n, hClk)
|
|
begin
|
|
if not(hReset_n) = '1' then
|
|
addressReg <= (others => '0');
|
|
writeReg <= '0';
|
|
selPeriph1Reg <= '0';
|
|
selPeriph2Reg <= '0';
|
|
elsif rising_edge(hClk) then
|
|
writeReg <= '0';
|
|
if (hSel = '1') and (hTrans = transNonSeq) then
|
|
addressReg <= hAddr;
|
|
writeReg <= hWrite;
|
|
selPeriph1Reg <= hSelPeriph1;
|
|
selPeriph2Reg <= hSelPeriph2;
|
|
end if;
|
|
end if;
|
|
end process storeControls;
|
|
-- write registers
|
|
storeRegisters: process(hReset_n, hClk)
|
|
begin
|
|
if not(hReset_n) = '1' then
|
|
registerArray <= (others => (others => '0'));
|
|
elsif rising_edge(hClk) then
|
|
if writeReg = '1' then
|
|
registerArray(to_integer(addressReg)) <= hWData;
|
|
end if;
|
|
end if;
|
|
end process storeRegisters;
|
|
-- read egisters
|
|
hRDataPeriph1 <= registerArray(to_integer(addressReg))
|
|
when addressReg < periph2BaseAddress
|
|
else (others => '-');
|
|
hReadyPeriph1 <= '1'; -- no wait state
|
|
hRespPeriph1 <= '0'; -- data OK
|
|
|
|
hRDataPeriph2 <= registerArray(to_integer(addressReg))
|
|
when addressReg >= periph2BaseAddress
|
|
else (others => '-');
|
|
hReadyPeriph2 <= '1'; -- no wait state
|
|
hRespPeriph2 <= '0'; -- data OK
|
|
|
|
END ARCHITECTURE test;
|