Skip to content

Commit

Permalink
Bugfixes: reset polarity simple cc and async fifo
Browse files Browse the repository at this point in the history
  • Loading branch information
BenoitStef committed May 31, 2024
1 parent 7630c40 commit 8df502c
Show file tree
Hide file tree
Showing 7 changed files with 228 additions and 35 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
#Pycharm project files
**/.idea
*.pyc

#Sim
sim/wlf*
7 changes: 7 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 3.0.1
* Bugfixes
* pulse_cc add testbench to check reset crossing and correct polarity handling
* modify simple_cc_tb to cope with bugfix in pulse_cc
* correct async fifo to work with reset polarity neg
* add few polarity check in test regression config.tcl

## 3.0.0
* Cleaning
* All codes have been unified for better readibility and all tabs have been removed
Expand Down
6 changes: 5 additions & 1 deletion hdl/psi_common_async_fifo.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ begin
end if;
end if;
-- Artificially keep InRdy low during reset if required
if (rdy_rst_state_g = '0') and (RstInInt = '1') then
if (rdy_rst_state_g = '0') and (RstInInt = rst_pol_g) then
in_rdy_o <= '0';
end if;

Expand Down Expand Up @@ -272,6 +272,10 @@ begin

-- only used for reset crossing and oring
i_rst_cc : entity work.psi_common_pulse_cc
generic map(
a_rst_pol_g => rst_pol_g,
b_rst_pol_g => rst_pol_g
)
port map(
-- Clock Domain A
a_clk_i => in_clk_i,
Expand Down
80 changes: 54 additions & 26 deletions hdl/psi_common_pulse_cc.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use ieee.numeric_std.all;
entity psi_common_pulse_cc is
generic(num_pulses_g : positive := 1; -- fifo width
a_rst_pol_g : std_logic:= '1'; -- rst polarity port A
b_rst_pol_g : std_logic:='1' ); -- rst polarity port B
b_rst_pol_g : std_logic:= '1'); -- rst polarity port B
port( a_clk_i : in std_logic; -- clock port a input
a_rst_i : in std_logic; -- rst input port a
a_rst_o : out std_logic; -- Clock domain A reset output, active if *a_rst_i* or *b_rst_i* is asserted, de-asserted synchronously to *a_clk_i*
Expand All @@ -40,76 +40,104 @@ architecture rtl of psi_common_pulse_cc is

-- Domain A signals
signal RstSyncB2A : std_logic_vector(3 downto 0);
signal RstAI : std_logic;
signal RstAI : std_logic := a_rst_pol_g;
-- Domain B signals
signal RstSyncA2B : std_logic_vector(3 downto 0);
signal RstBI : std_logic;
signal RstBI : std_logic := b_rst_pol_g;
-- Data transmit side
signal ToggleA : std_logic_vector(num_pulses_g - 1 downto 0);
-- Data receive side
signal ToggleSyncB : Pulse_t(2 downto 0);

attribute syn_srlstyle : string;
attribute syn_srlstyle of RstSyncB2A : signal is "registers";
attribute syn_srlstyle of RstSyncA2B : signal is "registers";
attribute syn_srlstyle of ToggleA : signal is "registers";
attribute syn_srlstyle : string;
attribute syn_srlstyle of RstSyncB2A : signal is "registers";
attribute syn_srlstyle of RstSyncA2B : signal is "registers";
attribute syn_srlstyle of ToggleA : signal is "registers";
attribute syn_srlstyle of ToggleSyncB : signal is "registers";

attribute shreg_extract : string;
attribute shreg_extract : string;
attribute shreg_extract of RstSyncB2A : signal is "no";
attribute shreg_extract of RstSyncA2B : signal is "no";
attribute shreg_extract of ToggleA : signal is "no";
attribute shreg_extract of ToggleSyncB : signal is "no";
attribute shreg_extract of ToggleA : signal is "no";
attribute shreg_extract of ToggleSyncB: signal is "no";

attribute ASYNC_REG : string;
attribute ASYNC_REG of RstSyncB2A : signal is "TRUE";
attribute ASYNC_REG of RstSyncA2B : signal is "TRUE";
attribute ASYNC_REG of ToggleA : signal is "TRUE";
attribute ASYNC_REG of ToggleSyncB : signal is "TRUE";
attribute ASYNC_REG : string;
attribute ASYNC_REG of RstSyncB2A : signal is "TRUE";
attribute ASYNC_REG of RstSyncA2B : signal is "TRUE";
attribute ASYNC_REG of ToggleA : signal is "TRUE";
attribute ASYNC_REG of ToggleSyncB : signal is "TRUE";

begin

-- Domain A reset sync
ARstSync_p : process(a_clk_i, b_rst_i)
begin
if b_rst_i = b_rst_pol_g then
RstSyncB2A <= (others => '1');
RstSyncB2A <= (others => b_rst_pol_g);
elsif rising_edge(a_clk_i) then
RstSyncB2A <= RstSyncB2A(RstSyncB2A'left - 1 downto 0) & '0';
RstSyncB2A <= RstSyncB2A(RstSyncB2A'left - 1 downto 0) & not b_rst_pol_g;
end if;
end process;

ARst_p : process(a_clk_i)
begin
if rising_edge(a_clk_i) then
if a_rst_pol_g = '1' then
RstAI <= RstSyncB2A(RstSyncB2A'left) or a_rst_i;
if b_rst_pol_g = '1' then
RstAI <= RstSyncB2A(RstSyncB2A'left) or a_rst_i;
else
RstAI <= RstSyncB2A(RstSyncB2A'left) and a_rst_i;
end if;
else
RstAI <= RstSyncB2A(RstSyncB2A'left) and a_rst_i;
if b_rst_pol_g = '1' then
RstAI <= RstSyncB2A(RstSyncB2A'left) or a_rst_i;
else
RstAI <= RstSyncB2A(RstSyncB2A'left) and a_rst_i;
end if;
end if;
end if;
end process;
a_rst_o <= RstAI;
gene_a_rst_o : if a_rst_pol_g = '1' generate
a_rst_o <= RstAI or a_rst_i;
end generate;
gene_a_rst_o_neg : if a_rst_pol_g = '0' generate
a_rst_o <= RstAI and a_rst_i;
end generate;

-- Domain B reset sync
BRstSync_p : process(b_clk_i, a_rst_i)
begin
if a_rst_i = a_rst_pol_g then
RstSyncA2B <= (others => '1');
RstSyncA2B <= (others => a_rst_pol_g);
elsif rising_edge(b_clk_i) then
RstSyncA2B <= RstSyncA2B(RstSyncA2B'left - 1 downto 0) & '0';
RstSyncA2B <= RstSyncA2B(RstSyncA2B'left - 1 downto 0) & not a_rst_pol_g;
end if;
end process;

BRst_p : process(b_clk_i)
begin
if rising_edge(b_clk_i) then
if b_rst_pol_g = '1' then
RstBI <= RstSyncA2B(RstSyncA2B'left) or b_rst_i;
if a_rst_pol_g = '1' then
RstBI <= RstSyncA2B(RstSyncA2B'left) or b_rst_i;
else
RstBI <= RstSyncA2B(RstSyncA2B'left) and b_rst_i;
end if;
else
RstBI <= RstSyncA2B(RstSyncA2B'left) and b_rst_i;
if a_rst_pol_g = '1' then
RstBI <= RstSyncA2B(RstSyncA2B'left) or b_rst_i;
else
RstBI <= RstSyncA2B(RstSyncA2B'left) and b_rst_i;
end if;
end if;
end if;
end process;
b_rst_o <= RstBI;
gene_b_rst_o : if b_rst_pol_g = '1' generate
b_rst_o <= RstBI or b_rst_i;
end generate;
gene_b_rst_o_neg : if b_rst_pol_g = '0' generate
b_rst_o <= RstBI and b_rst_i;
end generate;

-- Pulse transmit side (A)
PulseA_p : process(a_clk_i)
Expand All @@ -136,5 +164,5 @@ begin
end if;
end if;
end process;

end architecture;

15 changes: 15 additions & 0 deletions sim/config.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,23 @@ add_sources "../testbench" {
psi_common_prbs_tb/maximal_length_lfsr.vhd \
psi_common_prbs_tb/psi_common_prbs_tb.vhd \
psi_common_pwm_tb/psi_common_pwm_tb.vhd \
psi_common_pulse_cc_tb/psi_common_pulse_cc_tb.vhd \
} -tag tb

#TB Runs

create_tb_run "psi_common_pulse_cc_tb"
tb_run_add_arguments \
"-ga_freq_clk_g=100.0E6 -gb_freq_clk_g=50.0E6 -gnum_pulses_g=1 -ga_rst_pol_g='1' -gb_rst_pol_g='1' -ga_rst_before_g=true" \
"-ga_freq_clk_g=100.0E6 -gb_freq_clk_g=50.0E6 -gnum_pulses_g=1 -ga_rst_pol_g='0' -gb_rst_pol_g='0' -ga_rst_before_g=true" \
"-ga_freq_clk_g=100.0E6 -gb_freq_clk_g=50.0E6 -gnum_pulses_g=1 -ga_rst_pol_g='1' -gb_rst_pol_g='0' -ga_rst_before_g=true" \
"-ga_freq_clk_g=100.0E6 -gb_freq_clk_g=50.0E6 -gnum_pulses_g=1 -ga_rst_pol_g='0' -gb_rst_pol_g='1' -ga_rst_before_g=true" \
"-ga_freq_clk_g=100.0E6 -gb_freq_clk_g=50.0E6 -gnum_pulses_g=1 -ga_rst_pol_g='1' -gb_rst_pol_g='1' -ga_rst_before_g=false" \
"-ga_freq_clk_g=100.0E6 -gb_freq_clk_g=50.0E6 -gnum_pulses_g=1 -ga_rst_pol_g='0' -gb_rst_pol_g='0' -ga_rst_before_g=false" \
"-ga_freq_clk_g=100.0E6 -gb_freq_clk_g=50.0E6 -gnum_pulses_g=1 -ga_rst_pol_g='1' -gb_rst_pol_g='0' -ga_rst_before_g=false" \
"-ga_freq_clk_g=100.0E6 -gb_freq_clk_g=50.0E6 -gnum_pulses_g=1 -ga_rst_pol_g='0' -gb_rst_pol_g='1' -ga_rst_before_g=false"
add_tb_run

create_tb_run "psi_common_min_max_sum_tb"
tb_run_add_arguments \
"-gclock_cycle_g=100 -gsigned_data_g=true -gdata_length_g=16 -gaccu_length_g=64" \
Expand Down Expand Up @@ -245,6 +259,7 @@ add_tb_run
create_tb_run "psi_common_async_fifo_tb"
tb_run_add_arguments \
"-gafull_on_g=true -gaempty_on_g=true -gdepth_g=32 -gram_behavior_g=RBW -grdy_rst_state_g=1" \
"-gafull_on_g=true -gaempty_on_g=true -gdepth_g=32 -gram_behavior_g=RBW -grdy_rst_state_g=1 -grst_pol_g='0'" \
"-gafull_on_g=true -gaempty_on_g=true -gdepth_g=32 -gram_behavior_g=RBW -grdy_rst_state_g=0" \
"-gafull_on_g=false -gaempty_on_g=false -gdepth_g=128 -gram_behavior_g=RBW" \
"-gafull_on_g=false -gaempty_on_g=false -gdepth_g=128 -gram_behavior_g=WBR"
Expand Down
18 changes: 10 additions & 8 deletions testbench/psi_common_async_fifo_tb/psi_common_async_fifo_tb.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ entity psi_common_async_fifo_tb is
aempty_on_g : boolean := true;
depth_g : natural := 32;
ram_behavior_g : string := "RBW";
rdy_rst_state_g : integer range 0 to 1 := 1
rdy_rst_state_g : integer range 0 to 1 := 1;
rst_pol_g : std_logic := '1'
);
end entity psi_common_async_fifo_tb;

Expand Down Expand Up @@ -50,9 +51,9 @@ architecture sim of psi_common_async_fifo_tb is
-- Interface Signals
-------------------------------------------------------------------------
signal in_clk_i : std_logic := '0';
signal in_rst_i : std_logic := '1';
signal in_rst_i : std_logic := rst_pol_g;
signal out_clk_i : std_logic := '0';
signal out_rst_i : std_logic := '1';
signal out_rst_i : std_logic := rst_pol_g;
signal in_dat_i : std_logic_vector(DataWidth_c - 1 downto 0) := (others => '0');
signal in_vld_i : std_logic := '0';
signal in_rdy_o : std_logic := '0';
Expand Down Expand Up @@ -84,7 +85,8 @@ begin
aempty_on_g => aempty_on_g,
aempty_level_g => AlmEmptyLevel_c,
ram_behavior_g => ram_behavior_g,
rdy_rst_state_g => int_to_std_logic(rdy_rst_state_g)
rdy_rst_state_g => int_to_std_logic(rdy_rst_state_g),
rst_pol_g => rst_pol_g
)
port map(
-- Control Ports
Expand Down Expand Up @@ -149,8 +151,8 @@ begin
-- *** Reset Tests ***
print(">> Reset");
-- Reset
in_rst_i <= '1';
out_rst_i <= '1';
in_rst_i <= rst_pol_g;
out_rst_i <= rst_pol_g;
-- check if ready state during reset is correct
wait for 20 ns; -- reset must be transferred to other clock domain
wait until rising_edge(in_clk_i);
Expand All @@ -159,9 +161,9 @@ begin

-- Remove reset
wait until rising_edge(in_clk_i);
in_rst_i <= '0';
in_rst_i <= not rst_pol_g;
wait until rising_edge(out_clk_i);
out_rst_i <= '0';
out_rst_i <= not rst_pol_g;
wait for 100 ns;

-- Check Reset State
Expand Down
Loading

0 comments on commit 8df502c

Please sign in to comment.