Commit d1c126b0 authored by Jorge Machado's avatar Jorge Machado

Create immediate pulse train generator

parent b180b926
-------------------------------------------------------------------------------
-- Title : Immediate pulse train generator
-- Project : White Rabbit Network Interface
-------------------------------------------------------------------------------
-- File : imm_pulse_train_gen.vhd
-- Author : Jorge Machado
-- Company : Seven Solutions
-- Created : 2020-03-19
-- Last update:
-- Platform : FPGA-generic
-- Standard : VHDL
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity imm_pulse_train_gen is
generic(
pulse_period_width : integer := 28
);
port(
clk_ref_i : in std_logic;
rst_n_i : in std_logic;
dio_pulse_immed_stb_i : in std_logic;
pulse_period_i : in std_logic_vector(pulse_period_width-1 downto 0);
pulse_output_o : out std_logic
);
end imm_pulse_train_gen;
architecture Behavioral of imm_pulse_train_gen is
signal nozeroperiod, nozeroperiod_aux : boolean;
signal dio_pulse_immed_stb_d0, dio_pulse_immed_stb_d1,
dio_pulse_immed_stb_d2, dio_pulse_immed_stb_d3 : std_logic;
-- Internal registers to hold pulse duration
signal counter : unsigned (pulse_period_width-1 downto 0);
-- Signals for states
type counter_state is (WAIT_ST, COUNTING, CAPTURE_PERIOD, TRIGGER);
signal state : counter_state;
signal repeat_pulse : std_logic;
-- Aux
constant zeros : std_logic_vector(pulse_period_width-1 downto 0) := (others => '0');
constant initial_pulse_delay_compensation : integer := 7;
constant repeat_pulse_delay_compensation : integer := 4;
begin
synchronization : process(clk_ref_i, rst_n_i)
begin
if (rst_n_i = '0') then
dio_pulse_immed_stb_d0 <= '0';
dio_pulse_immed_stb_d1 <= '0';
dio_pulse_immed_stb_d2 <= '0';
dio_pulse_immed_stb_d3 <= '0';
elsif rising_edge(clk_ref_i) then
dio_pulse_immed_stb_d0 <= dio_pulse_immed_stb_i;
dio_pulse_immed_stb_d1 <= dio_pulse_immed_stb_d0;
dio_pulse_immed_stb_d2 <= dio_pulse_immed_stb_d1;
dio_pulse_immed_stb_d3 <= dio_pulse_immed_stb_d2;
nozeroperiod_aux <= pulse_period_i /= zeros;
if ((dio_pulse_immed_stb_d2 = '1' and dio_pulse_immed_stb_d1 = '0') or (state = CAPTURE_PERIOD)) then
nozeroperiod <= nozeroperiod_aux;
end if;
end if;
end process;
state_process : process(clk_ref_i, rst_n_i)
begin
if (rst_n_i = '0') then
counter <= (others => '0');
state <= WAIT_ST;
repeat_pulse <= '0';
elsif rising_edge(clk_ref_i) then
case state is
when WAIT_ST =>
if dio_pulse_immed_stb_d3 = '1' and nozeroperiod then
state <= COUNTING;
--Store the period two cycle before than the immed_pulse_counter_process to not lost one cycle.
counter <= unsigned(pulse_period_i)-initial_pulse_delay_compensation;
elsif repeat_pulse = '1' and nozeroperiod then
state <= COUNTING;
--Store the period four cycles before
counter <= unsigned(pulse_period_i)-repeat_pulse_delay_compensation;
else
state <= WAIT_ST;
end if;
when COUNTING =>
if (counter = 0) then
state <= CAPTURE_PERIOD;
else
state <= COUNTING;
counter <= counter-1;
end if;
when CAPTURE_PERIOD =>
state <= TRIGGER;
when TRIGGER =>
state <= WAIT_ST;
if(nozeroperiod) then
repeat_pulse <= '1';
else
repeat_pulse <= '0';
end if;
when others =>
state <= WAIT_ST;
end case;
end if;
end process;
output_process : process(counter, state)
begin
if (rst_n_i = '0') then
pulse_output_o <= '0';
else
case state is
when WAIT_ST =>
pulse_output_o <= '0';
when COUNTING =>
pulse_output_o <= '0';
when TRIGGER =>
pulse_output_o <= '1';
when others =>
pulse_output_o <= '0';
end case;
end if;
end process;
end Behavioral;
......@@ -211,6 +211,19 @@ architecture rtl of xwr_dio is
);
end component;
component imm_pulse_train_gen
generic(
pulse_period_width : integer := 28
);
port(
clk_ref_i : in std_logic;
rst_n_i : in std_logic;
dio_pulse_immed_stb_i : in std_logic;
pulse_period_i : in std_logic_vector(pulse_period_width-1 downto 0);
pulse_output_o : out std_logic
);
end component;
component wr_dio_wb is
port (
rst_n_i : in std_logic;
......@@ -621,6 +634,26 @@ begin
tag_cycles_o => tag_cycles(5),
tag_valid_o => tag_valid_p1(5));
------------------------------------------------------------------------------
-- PULSE TRAIN GENERATOR
------------------------------------------------------------------------------
gen_pulse_train_modules : for i in 0 to 5 generate
U_imm_pulse_train_gen : imm_pulse_train_gen
generic map(
pulse_period_width => 28
)
port map(
clk_ref_i => clk_ref_i,
rst_n_i => rst_n_i,
dio_pulse_immed_stb_i => dio_pulse_immed_stb(i),
pulse_period_i => pulse_period(i),
pulse_output_o => dio_pulse_immed_periodic(i)
);
end generate gen_pulse_train_modules;
------------------------------------------------------------------------------
-- WB ONEWIRE MASTER
------------------------------------------------------------------------------
......@@ -734,7 +767,16 @@ begin
slave_o.err <= slave_bypass_o.err;
slave_o.rty <= slave_bypass_o.rty;
immediate_output_with_pulse_length : for i in 0 to 4 generate
-- The input of the immediate pulse counter is now a result of an OR between original stb
-- and the generated in the periodic immediate pulse core
dio_pulse_immed_result(0) <= dio_pulse_immed_stb(0) or dio_pulse_immed_periodic(0);
dio_pulse_immed_result(1) <= dio_pulse_immed_stb(1) or dio_pulse_immed_periodic(1);
dio_pulse_immed_result(2) <= dio_pulse_immed_stb(2) or dio_pulse_immed_periodic(2);
dio_pulse_immed_result(3) <= dio_pulse_immed_stb(3) or dio_pulse_immed_periodic(3);
dio_pulse_immed_result(4) <= dio_pulse_immed_stb(4) or dio_pulse_immed_periodic(4);
dio_pulse_immed_result(5) <= dio_pulse_immed_stb(5) or dio_pulse_immed_periodic(5);
immediate_output_with_pulse_length : for i in 0 to 5 generate
immediate_output_component : immed_pulse_counter
generic map (
pulse_length_width => 28
......@@ -742,7 +784,7 @@ begin
port map(
clk_i => clk_ref_i,
rst_n_i => rst_n_i,
pulse_start_i => dio_pulse_immed_stb(i),
pulse_start_i => dio_pulse_immed_result(i),
pulse_length_i => pulse_length(i),
pulse_output_o => dio_pulse_immed(i)
);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment