SLT logic features some pulse producing circuit elements which are used in many places inside an 1130 or 360 computer. As these were built and controlled by selecting capacitors and RC networks on the SLT card, something not possible within an FPGA, they also needed to be modeled in a way that would produce the intended behavior. These modules I wrote to accomplish these functions are also instantiated in any code as a one to one substitute for the SLT elements in an ALD diagram. An ALD page could be represented by standard VHDL logic plus the substitute modules for FF, edge sensitive gates and these other element types, thus remaining very true to the circuit design.
Single Shots (SS) are an SLT element that fires off a pulse of some duration chosen by the designer thru the specification of capacitor and resistor values to be connected to the element. For example, a given circuit might want a pulse of 250 microseconds duration to occur. The SS would fire a pulse whenever its input went on - it was edge sensitive. If the input remained on for a long time, it didn't matter, the pulse from the SS element would be 250 microseconds or whatever timing the designer chose. My module SingleShot is a variant written to provide a pure SS drop in substitute.
Sample Pulse Driver (SPD) elements will take a logic signal and fire off a short pulse when the logic signal switches on. It is essentially an edge sensitive gate like my EdgeGate which has has a 'gate' input that is always true, thus it fires the pulse any and every time the 'shift' input produces the edge we are looking for.
SS elements are behaviorally like SPD elements except the duration of the pulse is extended for some target interval in the SS, which could even be hundreds of milliseconds long; the SPD produces a short pulse about the speed of one gate delay in SLT terms.
One final circuit need is for a delay, an element which will cause the signal to be delayed in time but otherwise follow the same pattern as the input signal. I wrote the Delay module as the means to cleanly insert a chosen delay into a circuit.
The SingleShot and Delay modules are hybrids of async and clock sync techniques, much like the EdgeGate from which they are derived, since the triggers could arrive at any point unrelated to the master clock of the FPGA, even one as fast as the 20ns clock in our implementation board. The clock sync portion is used to produce given timings for pulse durations or delays of signals.
Delay is used less than ten times in the entire 1130 implementation, since the 1130 designer implemented any desired delays by passing signals through several gates to introduce minor delays, not by placing a specific 'delay' type gate in the ALD. These were used only in the cases where signals had to be delayed for correct operation, something found to be very rare in the operation of the 1130 logic inside my recreation.
Here is the SingleShot module for the reader interested in the details:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
-- This function will fire off a pulse of a preconfigured duration
-- when the trigger edge arrives. It can be configured to trigger
-- on the 0->1 or 1->0 edge, it can be configured to provide a positive
-- or inverted pulse, and the duration is defined for the instance
entity SingleShot is
Generic ( invtrigger : integer := 0;
invreset : integer := 0;
ctrload : integer := 1;
ctrsize : natural := 2;
invpulse : integer := 0);
Port ( Trigger : in STD_LOGIC;
ClockMaster : in STD_LOGIC;
DCReset : in STD_LOGIC;
Output : out STD_LOGIC);
end SingleShot;
architecture Behavioral of SingleShot is
signal Pulse : std_logic := '0';
signal Shift : std_logic;
signal Edge : std_logic;
signal Reset : std_logic;
signal Ctr : std_logic_vector(ctrsize-1 downto 0);
constant empty : integer := 0;
begin
-- output is positive going or inverse if wedged (invpulse /= 0)
go1 : if invpulse = 0 generate
Output <= Pulse;
end generate;
go2 : if invpulse /= 0 generate
Output <= not Pulse;
end generate;
-- trigger is 0->1 edge (P) or inverse (N) if invtrigger /= 0
gs1 : if invtrigger = 0 generate
Shift <= Trigger;
end generate;
gs2 : if invtrigger /= 0 generate
Shift <= not Trigger;
end generate;
-- set up for either pos or inverted reset as requested by caller
gr1 : if invreset = 0 generate
Reset <= DCReset;
end generate;
gr2 : if invreset /= 0 generate
Reset <= not DCReset;
end generate;
process (Shift, Pulse, Reset)
begin
-- make sure we don't do anything bad at startup like emit or trigger spuriously
if Reset = '1' then
Edge <= '0';
-- if we started emitting an output pulse, shut down detection signal
elsif Pulse = '1' then
Edge <= '0';
-- if our shift occured and we are not already emitting, signal we should start
elsif Shift'event and Shift = '1'
and Ctr = std_logic_vector(to_unsigned(empty,ctrsize)) then
Edge <= '1';
end if;
end process;
process (ClockMaster, Ctr, Edge, Reset)
begin
-- at startup, make sure we don't trigger or emit anything spurious
if Reset = '1' then
Ctr <= (others => '0');
Pulse <= '0';
-- we detected an edge, load our counter and indicate we are emitting
elsif Edge = '1' then
Ctr <= std_logic_vector(to_unsigned(ctrload,ctrsize));
Pulse <= '1';
-- do our clock synchronous thing with the counter
elsif ClockMaster'event and ClockMaster = '1' then
-- if we have a positive count, decrement it and keep emitting
If to_integer( unsigned(ctr)) /= 0 then
Pulse <= '1';
Ctr <= std_logic_vector(
to_unsigned((to_integer( unsigned(ctr) ) - 1 ),ctrsize));
-- otherwise we are done, shut off pulse
else
Pulse <= '0';
end if;
end if;
end process;
end Behavioral;
No comments:
Post a Comment