This allowed the designer to make use of both long lasting signals reflecting logical conditions and of pulses to be driven at specific times. A signal such as "XIO instruction" might be on during most of the cycles when an XIO (execute input-output) instruction is active, and that could be one of the conditions that are combined to activate a specific circuit at some chosen time. If an XIO instruction of a certain type, such as a initiate read, is being executed, then we might want to cause the value read from memory to be set into a specific machine register. If that data is read during the E2 cycle while processing the instruction and the data is valid when the T3 cycle of E2 begins, we might have combinatorial logic mixing the 'XIO instruction' signal with signals for 'E2' and signals that identify this as an initiate-read type of XIO. Those relatively long lasting signals are used as the 'gate' input while the signal for being in a T3 cycle is used as the 'shift'. Our gate will fire a pulse if all of 'XIO instruction', 'E2' and "i nitiate read' are true, at the time that the T3 signal shifts from 0 to 1 (we begin the T3 cycle within the longer E2 cycle of the even longer single instruction XIO). This pulse from our gate might trigger the 'set' of a given register that will cause it to be loaded with the value just read from memory.
This is how an async design can have vaguely clock-like cycles and cause some actions to happen at chosen times. Note that the pulse causing the loading of the register, in our example above, might occur at a time that has no specific relationship to other timings in the machine - it could be ahead or behind other pulses generated at the start of T3, as each portion of the machine operates solely based on pulses and signal levels it sees, unconstrained by any global synchronizing clock.
I called this function EdgeGate and instantiate copies of this module for any gate in the 1130 design that is edge triggered. It receives a gate and a shift input, is secretly clocked by the FPGA master clock running at 50MHz, thus is able to produce a pulse of a chosen duration as its output. Fully configurable for the polarity of the inputs, the polarity of the output pulse and the duration in fpga cycles of the pulse itself.
The entire VHDL of this function is posted for those readers who wish to see how it was implemented in more detail:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity EdgeTriggerGate is
Generic ( invgate : integer := 0;
invshift : integer := 0;
invout : integer := 0);
Port ( Gate : in STD_LOGIC;
Shift : in STD_LOGIC;
ClockMaster : in STD_LOGIC;
Output : out STD_LOGIC);end EdgeTriggerGate;
architecture Behavioral of EdgeTriggerGate is
signal Edge : std_logic := '0';
signal Pulse : std_logic := '0';
signal Gated : std_logic := '0';
signal Trigger : std_logic := '1';
signal DelayedGate : std_logic := '1';
constant empty : integer := 0;
begin
-- this just delays a copy of the gate signal, so that we can
-- verify that it is stable and not changing or glitching
DelayedGate <= not (not (not (not Gated))) after 2 ns;
-- output is normal or inverse if wedged (invout /= 0)
go1 : if invout = 0 generate
Output <= Pulse;
end generate;
go2 : if invout /= 0 generate
Output <= not Pulse;
end generate;
-- Level sensitive input is 0->1 edge (P) or inverse (N) if invshift /= 0
gs1 : if invshift = 0 generate
Trigger <= Shift;
end generate;
gs2 : if invshift /= 0 generate
Trigger <= not Shift;
end generate;
-- Gating signals normal or inverse (wedged) if invgate /= 0
gg1 : if invgate = 0 generate
Gated <= Gate;
end generate;
gg2 : if invgate /= 0 generate
Gated <= not Gate;
end generate;
process (Trigger, Pulse, Gated, DelayedGate)
begin
if Pulse = '1' then
Edge <= '0';
elsif Trigger'event and Trigger = '1' and
(Gated and DelayedGate) = '1' then
Edge <= '1';
end if;
end process;
process (ClockMaster, Edge)
begin
if ClockMaster'event and ClockMaster = '1' then
Pulse <= Edge;
end if;
end process;
end Behavioral;
No comments:
Post a Comment