Skip to content
Snippets Groups Projects
Commit c8205156 authored by Tristan Gingold's avatar Tristan Gingold
Browse files

gc_sync_word_wr: improve speed (use toggling).

parent 17a1843c
Branches
Tags
No related merge requests found
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
-- Used to transfer a word from the input clock domain to the output clock -- Used to transfer a word from the input clock domain to the output clock
-- domain. User provides the data and a pulse write signal to transfer the -- domain. User provides the data and a pulse write signal to transfer the
-- data. When the data are transfered, a write pulse is generated on the -- data. When the data are transfered, a write pulse is generated on the
-- output side along with the data, and an acknowledge is geenrated on the -- output side along with the data, and an acknowledge is generated on the
-- input side. Once the user request a transfer, no new data should be -- input side. Once the user request a transfer, no new data should be
-- requested for a transfer until the ack was received. -- requested for a transfer until the ack was received.
-- --
...@@ -52,44 +52,46 @@ entity gc_sync_word_wr is ...@@ -52,44 +52,46 @@ entity gc_sync_word_wr is
end entity; end entity;
architecture behav of gc_sync_word_wr is architecture behav of gc_sync_word_wr is
signal data : std_logic_vector (width - 1 downto 0); signal data : std_logic_vector (width - 1 downto 0);
signal in_busy : std_logic; signal in_busy : std_logic;
signal in_progress : std_logic; signal start_wr : std_logic;
signal ack_start, ack_done : std_logic;
-- Synchronized extended wr_i signal. -- Synchronized extended wr_i signal.
signal wr_out : std_logic; signal wr_out : std_logic;
-- Internal pulse for wr_o, active one cycle before wr_o. signal last_wr_out : std_logic;
signal wr_out_p : std_logic; signal wr_out_fb : std_logic;
signal last_wr_out_fb : std_logic;
begin begin
-- Handle incoming request. -- Handle incoming request.
process(clk_in_i) process(clk_in_i)
begin begin
if rising_edge(clk_in_i) then if rising_edge(clk_in_i) then
if rst_in_n_i = '0' then if rst_in_n_i = '0' then
in_progress <= '0'; start_wr <= '0';
in_busy <= '0'; in_busy <= '0';
data <= (others => '0'); data <= (others => '0');
ack_o <= '0'; ack_o <= '0';
last_wr_out_fb <= '0';
else else
ack_o <= '0'; ack_o <= '0';
if in_busy = '0' then if in_busy = '0' then
if wr_i = '1' then if wr_i = '1' then
in_progress <= '1'; -- Write requested.
-- Toggle start_wr ...
start_wr <= not start_wr;
in_busy <= '1'; in_busy <= '1';
data <= data_i; data <= data_i;
end if; end if;
else else
assert wr_i = '0' report "request while previous one not completed" assert wr_i = '0' report "request while previous one not completed"
severity error; severity error;
if ack_start = '1' then -- ... and wait until wr_out_fb has been toggled.
in_progress <= '0'; if (wr_out_fb xor last_wr_out_fb) = '1' then
end if; -- Set ack (for one cycle).
if ack_done = '1' then
assert in_progress = '0';
in_busy <= '0';
ack_o <= '1'; ack_o <= '1';
last_wr_out_fb <= wr_out_fb;
-- Ready for a new request.
in_busy <= '0';
end if; end if;
end if; end if;
end if; end if;
...@@ -100,9 +102,8 @@ begin ...@@ -100,9 +102,8 @@ begin
port map ( port map (
clk_i => clk_out_i, clk_i => clk_out_i,
rst_n_i => rst_out_n_i, rst_n_i => rst_out_n_i,
data_i => in_progress, data_i => start_wr,
synced_o => wr_out, synced_o => wr_out);
ppulse_o => wr_out_p);
-- Outputs. -- Outputs.
process (clk_out_i) process (clk_out_i)
...@@ -111,11 +112,13 @@ begin ...@@ -111,11 +112,13 @@ begin
if rst_out_n_i = '0' then if rst_out_n_i = '0' then
data_o <= (others => '0'); data_o <= (others => '0');
wr_o <= '0'; wr_o <= '0';
last_wr_out <= '0';
else else
if wr_out_p = '1' then if (wr_out xor last_wr_out) = '1' then
-- Data are stable. -- Data are stable.
data_o <= data; data_o <= data;
wr_o <= '1'; wr_o <= '1';
last_wr_out <= wr_out;
else else
wr_o <= '0'; wr_o <= '0';
end if; end if;
...@@ -129,6 +132,5 @@ begin ...@@ -129,6 +132,5 @@ begin
clk_i => clk_in_i, clk_i => clk_in_i,
rst_n_i => rst_in_n_i, rst_n_i => rst_in_n_i,
data_i => wr_out, data_i => wr_out,
ppulse_o => ack_start, synced_o => wr_out_fb);
npulse_o => ack_done);
end behav; end behav;
...@@ -11,5 +11,5 @@ radix -hexadecimal ...@@ -11,5 +11,5 @@ radix -hexadecimal
#add wave * #add wave *
do wave.do do wave.do
run 4 us run 400ns
wave zoomfull wave zoomfull
...@@ -10,12 +10,11 @@ add wave -noupdate /tb_gc_sync_word_wr/wri ...@@ -10,12 +10,11 @@ add wave -noupdate /tb_gc_sync_word_wr/wri
add wave -noupdate /tb_gc_sync_word_wr/wro add wave -noupdate /tb_gc_sync_word_wr/wro
add wave -noupdate /tb_gc_sync_word_wr/ack add wave -noupdate /tb_gc_sync_word_wr/ack
add wave -noupdate /tb_gc_sync_word_wr/cmp_tb/in_busy add wave -noupdate /tb_gc_sync_word_wr/cmp_tb/in_busy
add wave -noupdate /tb_gc_sync_word_wr/cmp_tb/in_progress add wave -noupdate /tb_gc_sync_word_wr/cmp_tb/wr_out
add wave -noupdate /tb_gc_sync_word_wr/cmp_tb/ack_start add wave -noupdate /tb_gc_sync_word_wr/cmp_tb/last_wr_out
add wave -noupdate /tb_gc_sync_word_wr/cmp_tb/ack_done
TreeUpdate [SetDefaultTree] TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {0 ps} 0} WaveRestoreCursors {{Cursor 1} {90000 ps} 0}
quietly wave cursor active 0 quietly wave cursor active 1
configure wave -namecolwidth 150 configure wave -namecolwidth 150
configure wave -valuecolwidth 100 configure wave -valuecolwidth 100
configure wave -justifyvalue left configure wave -justifyvalue left
...@@ -30,4 +29,4 @@ configure wave -griddelta 40 ...@@ -30,4 +29,4 @@ configure wave -griddelta 40
configure wave -timeline 0 configure wave -timeline 0
configure wave -timelineunits ps configure wave -timelineunits ps
update update
WaveRestoreZoom {0 ps} {262500 ps} WaveRestoreZoom {0 ps} {420 ns}
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