LIBRARY ieee; use ieee.std_logic_1164.all; entity i486_bus is generic (-- These specs are for the i486DX 50 constant t6_max:time:=12 ns; constant t10_min:time:=3 ns; constant t10_max:time:=12 ns; constant t11_max:time:=18 ns; constant t16_min:time:=5 ns; constant t17_min:time:=3 ns; constant t22_min:time:=5 ns; constant t23_min:time:=3 ns); port (--external interface abus: out bit_vector(31 downto 0); dbus: inout std_logic_vector(31 downto 0) := (others => 'Z'); w_rb, ads_b: out bit := '1'; rdy_b, clk: in bit; --internal interface address, w_data: in bit_vector(31 downto 0); r_data: out bit_vector(31 downto 0); wr, br: in bit; std, done:out bit); end i486_bus; --****************************************************************** architecture simple_486_bus of i486_bus is type state_t is (Ti, T1, T2); signal state, next_state:state_t:=Ti; --****************************************************************** begin -- The following process outputs the control signals and address of -- the processor during a read/write operation.The process also drives -- or tristates the databus depending on the operation type. -- During the execution of a read/write operation, the done signal -- is low. When the bus is ready to accept a new request, done is high. comb_logic: process begin std <= '0'; case (state) is when Ti=> done<='1'; if (br = '1') then next_state <= T1; else next_state <= Ti; end if; dbus <= transport (others =>'Z') after t10_min; when T1=> done <= '0'; ads_b <= transport '0' after t6_max; w_rb <= transport wr after t6_max; abus <= transport address after t6_max; dbus <= transport (others =>'Z') after t10_min; next_state <= T2; when T2=> ads_b <= transport '1' after t6_max; if (wr = '0') then -- read if (rdy_b ='0') then r_data <= to_bitvector(dbus); std <= '1'; done <= '1'; if (br = '0') then next_state <= Ti; else next_state <= T1; end if; else next_state <= T2; end if; else -- write dbus <= transport to_stdlogicvector(w_data) after t10_max; if (rdy_b = '0') then done<='1'; if (br = '0') then next_state <= Ti; else next_state <= T1; end if; else next_state <= T2; end if; end if; end case; wait on state, rdy_b, br, dbus; end process comb_logic; --****************************************************************** --The following process updates the current state on every rising clock edge seq_logic: process(clk) begin if (clk = '1') then state <= next_state; end if; end process seq_logic; --****************************************************************** --The following process checks that all setup and hold times are -- met for all incoming control signals. -- Setup and hold times are checked for the data bus during a read only wave_check: process (clk, dbus, rdy_b) variable clk_last_rise:time:= 0 ns; begin if (state=T2) then if clk'event and clk = '1' then --check setup times --The following assert assumes that the setup for RDY -- is equal to or greater than that for data assert (rdy_b /= '0') OR (wr /= '0') OR (dbus'last_event >= t22_min) report "i486 bus:Data setup too short" severity WARNING; assert (rdy_b'last_event >= t16_min) report "i486 bus:RDY setup too short" severity WARNING; clk_last_rise := NOW; end if; if (dbus'event) then --check hold times --The following assert assumes that the hold for RDY -- is equal to or greater than that for data assert (rdy_b /= '0') OR (wr /= '0') OR (now - clk_last_rise >= t23_min) report "i486 bus:Data hold too short" severity WARNING; end if; if (rdy_b'event) then assert (now - clk_last_rise >= t17_min) report "i486 bus: RDY signal hold too short" severity WARNING; end if; end if; end process wave_check; end simple_486_bus;