Monday, 30 October 2017

VHDL PULSE WIDTH



 Library IEEE; -- define library and packages needed for this design
 Use IEEE.std_logic_1164.All;

 Entity mode2n3 Is Port (
 clock20Mhz : In std_logic; -- Master input clock
 reset : In std_logic; -- Power-on reset
 input_pulse : In std_logic; -- Input for P1 & P3
 -------------------------------------
 narrow_pulse : Out std_logic; -- Indicates input pulse P1 or P3 is too narrow
 wide_pulse : Out std_logic; -- Indicates input pulse P1 or P3 is too wide
 invalid_mode : Out std_logic; -- Invalid P1 to P3 pulse spacing
 valid_pulse : Out std_logic; -- Indicates input pulse is valid
 mode2 : Out std_logic; -- Valid Mode2 decoded
 mode3A : Out std_logic); -- Valid Mode3 decoded
 ----------------------------------------
 End mode2n3;

 Architecture arch_mode2n3 Of mode2n3 Is
Signal int_narrow_pulse : std_logic;
 Signal int_wide_pulse : std_logic;
 Signal int_invalid_mode : std_logic;
 Signal int_valid_pulse : std_logic;
 Signal int_mode2 : std_logic;
Signal int_mode3A : std_logic;
 Signal risingedge : std_logic; -- Indicates the rising edge of P1 or P3
 Signal fallingedge : std_logic; -- Indicates the falling edge of P1 or P3
 Signal sync_pulse : std_logic; -- Converts async signal to sync

 Signal pulsewidth_counter : integer;
 Signal pulse_spacing : integer;
-- used “type” to define state machine states
 Type pulse_states Is (waitingP1, p1pulsewidth_check, waitingP3,p3pulsewidth_check, decode_mode);

Signal current_state : pulse_states;
Begin
 --begin assigning internal signals to corresponding output signals 
 narrow_pulse <= int_narrow_pulse;
 wide_pulse <= int_wide_pulse;
 mode2 <= int_mode2;
 mode3A <= int_mode3A;
 invalid_mode <= int_invalid_mode;
valid_pulse <= int_valid_pulse;
-- end assigning internal signals to corresponding output signals

--rising edge detection
 risingedge <= '1' When sync_pulse = '0' And input_pulse = '1'
Else '0';

-- falling edge detection
 fallingedge <= '1' When sync_pulse = '1' And input_pulse = '0'
Else '0';

 cur_state: Process (current_state, clock20Mhz, reset)
 Begin
 If reset = '1' Then -- assigning power-on or initial states values
pulsewidth_counter <= 0;
 pulse_spacing <= 0;
 int_narrow_pulse <= '0';
 int_wide_pulse <= '0';
 int_invalid_mode <= '0';
 int_valid_pulse <= '0';
-----------------------------------
 int_mode2 <= '0';
 int_mode3a <= '0';
current_state <= waitingP1;
 Elsif rising_edge (clock20Mhz) Then

 Case current_state Is
When waitingP1 => -- initial state waiting to receivefirst pulse P1
pulsewidth_counter <= 0; -- all signals are assignedinactive state values
 pulse_spacing <= 0;
int_narrow_pulse <= '0';
int_wide_pulse <= '0';
int_invalid_mode <= '0';
int_valid_pulse <= '0';
 int_mode2 <= '0';
int_mode3a <= '0';
 If risingedge = '1' Then -- Received P1 rising edge
 pulsewidth_counter <= pulsewidth_counter + 1;
-- start pulse width counter 
pulse_spacing <= pulse_spacing + 1;
-- start P1-P3 pulse spacing counter

 int_narrow_pulse <= '0';
 int_wide_pulse <= '0';
int_invalid_mode <= '0';
int_valid_pulse <= '0';
int_mode2 <= '0';
 int_mode3a <= '0';
 current_state <= p1pulsewidth_check;
-- move to next state & wait for P1falling edge
 Else
 current_state <= waitingp1;
End If;

When p1pulsewidth_check =>
If pulsewidth_counter = 19 Then -- P1 is wide
 pulsewidth_counter <= pulsewidth_counter;
 pulse_spacing <= pulse_spacing;
 int_narrow_pulse <= '0';
 int_wide_pulse <= '1'; -- Send out wide pulse signal
 int_invalid_mode <= '0';
 int_valid_pulse <= '0';
int_mode2 <= '0';
 int_mode3a <= '0';
 current_state <= waitingP1; -- Return to initial state and wait for P1
 Elsif fallingedge = '1' Then -- Received P1 falling edge
 If pulsewidth_counter <= 13 Then -- Pulse is narrow,stop counters
 pulsewidth_counter <= pulsewidth_counter;
 pulse_spacing <= pulse_spacing;
 int_narrow_pulse <= '1'; -- Narrow pulse signal is active
 int_wide_pulse <= '0';
 int_invalid_mode <= '0';
 int_valid_pulse <= '0';
 int_mode2 <= '0';
 int_mode3a <= '0';
 current_state <= waitingp1; -- Return to initial state and wait for P1
 Elsif pulsewidth_counter >= 14 And pulsewidth_counter <= 18
Then -- valid pulse
 pulsewidth_counter <= pulsewidth_counter;
 pulse_spacing <= pulse_spacing + 1;
 int_narrow_pulse <= '0';
int_wide_pulse <= '0';
 int_invalid_mode <= '0';
 int_valid_pulse <= '1'; -- P1 is good, activate valid pulse signal
 int_mode2 <= '0';
 int_mode3a <= '0';
 current_state <= waitingp3;
 End If;
 Else -- no falling edge or wide pulse, continue counting
 pulsewidth_counter <= pulsewidth_counter + 1;
pulse_spacing <= pulse_spacing + 1;
int_narrow_pulse <= int_narrow_pulse;
 int_wide_pulse <= int_wide_pulse;
 int_invalid_mode <= '0';
 int_valid_pulse <= int_valid_pulse;
 int_mode2 <= '0';
 int_mode3a <= '0';
 current_state <= p1pulsewidth_check;
 End If;

 When waitingP3 =>
 pulsewidth_counter <= 0;
 pulse_spacing <= pulse_spacing + 1; -- continuing counting P1-P3 pulse spacing
 int_narrow_pulse <= '0';
 int_wide_pulse <= '0';
 int_invalid_mode <= '0';
 int_valid_pulse <= '0';
 int_mode2 <= '0';
 int_mode3a <= '0';
 If pulse_spacing = 163 Then -- P1-P3 spacing too wide for Mode2 or Mode3
 pulsewidth_counter <= 0;
 pulse_spacing <= 0; -- stop counting
 int_narrow_pulse <= '0';
 int_wide_pulse <= '0';
 int_invalid_mode <= '1';
 int_valid_pulse <= '0';
 int_mode2 <= '0';
 int_mode3a <= '0';
 current_state <= waitingp1; -- wait for interrogation
 Elsif risingedge = '1' Then -- Received rising edge of P3
 If pulse_spacing <= 97 Or (pulse_spacing >= 104 And pulse_spacing <= 156) Then
 -- P1-P3 outside Mode2 or Mode3 range
 pulsewidth_counter <= 0;
 pulse_spacing <= 0; -- stop counting
 int_narrow_pulse <= '0';
 int_wide_pulse <= '0';
 int_invalid_mode <= '1';
 int_valid_pulse <= '0';
 int_mode2 <= '0';
 int_mode3a <= '0';
 current_state <= waitingp1; -- wait for interrogation
 Else
 pulsewidth_counter <= pulsewidth_counter + 1;
-- start pulse width counter
 pulse_spacing <= pulse_spacing;
-- stop pulse spacing counter
 int_narrow_pulse <= '0';
 int_wide_pulse <= '0';
 int_invalid_mode <= '0';
 int_valid_pulse <= '0';
 int_mode2 <= '0';
 int_mode3a <= '0';
 current_state <= p3pulsewidth_check;
 End If;
Else
 current_state <= waitingP3;
 End If;

 When p3pulsewidth_check =>
 If pulsewidth_counter = 19 Then -- wide pulse
 pulsewidth_counter <= pulsewidth_counter;
 pulse_spacing <= pulse_spacing;
 int_narrow_pulse <= '0';
 int_wide_pulse <= '1'; -- P3 is wide send out wide pulse signal
 int_invalid_mode <= '0';
 int_valid_pulse <= '0';
 int_mode2 <= '0';
 int_mode3a <= '0';
 current_state <= waitingP1; -- Return to waiting for rising edge of P1
 Elsif fallingedge = '1' Then -- detecting P3 falling edge
If pulsewidth_counter <= 13 Then -- narrow pulse
pulsewidth_counter <= pulsewidth_counter;
pulse_spacing <= pulse_spacing;
int_narrow_pulse <= '1'; -- send out narrow pulse signal
 int_wide_pulse <= '0';
 int_invalid_mode <= '0';
 int_valid_pulse <= '0';
 int_mode2 <= '0';
 int_mode3a <= '0';
 current_state <= waitingp1; -- Return to waiting for rising edge of P1
 Elsif pulsewidth_counter >= 14 And pulsewidth_counter <= 18
Then -- valid pulse
 pulsewidth_counter <= pulsewidth_counter;
 pulse_spacing <= pulse_spacing;
 int_narrow_pulse <= '0';
int_wide_pulse <= '0';
 int_invalid_mode <= '0';
int_valid_pulse <= '1'; -- P3 is good, activate valid pulse signal
 int_mode2 <= '0';
 int_mode3a <= '0';
 current_state <= decode_mode;
 End If;
 Else -- no fallinge edge
 pulsewidth_counter <= pulsewidth_counter + 1;
-- continue pulse width counting pulse_spacing <= pulse_spacing;
 int_narrow_pulse <= int_narrow_pulse;
 int_wide_pulse <= int_wide_pulse;
 int_invalid_mode <= int_invalid_mode;
int_valid_pulse <= int_valid_pulse;
 int_mode2 <= '0';
int_mode3a <= '0';
 current_state <= p3pulsewidth_check;
 End If;

 When decode_mode =>
 If (pulse_spacing >= 98 And pulse_spacing <= 102) Then -- pulse spacing between 4.9 and 5.1 us
pulsewidth_counter <= pulsewidth_counter;
 pulse_spacing <= pulse_spacing;
 int_narrow_pulse <= int_narrow_pulse;
 int_wide_pulse <= int_wide_pulse;
int_invalid_mode <= int_invalid_mode;
 int_valid_pulse <= int_valid_pulse;
 int_mode2 <= '1';
 int_mode3a <= '0';
 current_state <= waitingP1;
 Elsif (pulse_spacing >= 158 And pulse_spacing <= 162)Then
-- pulse spacing between 7.9 and 8.2 us
 pulsewidth_counter <= pulsewidth_counter;
 pulse_spacing <= pulse_spacing;
 int_narrow_pulse <= int_narrow_pulse;
 int_wide_pulse <= int_wide_pulse;
 int_invalid_mode <= int_invalid_mode;
 int_valid_pulse <= int_valid_pulse;
 int_mode2 <= '0';
 int_mode3a <= '1';
 current_state <= waitingP1;
 Else
 pulsewidth_counter <= pulsewidth_counter;
 pulse_spacing <= pulse_spacing;
 int_narrow_pulse <= int_narrow_pulse;
 int_wide_pulse <= int_wide_pulse;
 int_invalid_mode <= int_invalid_mode;
 int_valid_pulse <= int_valid_pulse;
 int_mode2 <= '0';
 int_mode3A <= '0';
 current_state <= waitingp1;
 End If;
When Others => -- if unknown state the signal will take on these values
 pulsewidth_counter <= 0;
 pulse_spacing <= 0;
 int_narrow_pulse <= '0';
 int_wide_pulse <= '0';
 int_invalid_mode <= '0';
 int_valid_pulse <= '0';
 int_mode2 <= '0';
 int_mode3A <= '0';
 current_state <= waitingp1;
 End Case;
 End If;
 End Process;

 edge_detect: Process (reset, clock20Mhz)
 --This process syncs input pulse to master clock. This signal is used for edge detection.
 Begin
 If reset = '1' Then
sync_pulse <= '0';
 Elsif rising_edge(clock20Mhz) Then
 sync_pulse <= input_pulse; -- input sync to master clock
 End If;
 End Process;
End arch_mode2n3;

No comments:

Post a Comment