URL
https://opencores.org/ocsvn/heap_sorter/heap_sorter/trunk
Subversion Repositories heap_sorter
Compare Revisions
- This comparison shows the changes necessary to convert path
/heap_sorter/trunk
- from Rev 5 to Rev 6
- ↔ Reverse comparison
Rev 5 → Rev 6
/high_speed_pipelined_4clk_per_word/README
1,5 → 1,12
This version is prepared for very high-speed setups. |
The memory uses additional output register. |
The comparator also uses additional pipeline register. |
|
The comparator also uses additional pipeline register, and is moved |
from the function defined in sorter_pkg.vhd to the external block: |
sorter_cmp_lt.vhd. |
That allows implementation better suited to the particular technology |
(e.g., usage of DSP48 blocks in Xilinx). |
IT IS IMPORTANT THAT THIS BLOCKS HAS EXACTLY 1 CLOCK LATENCY! |
|
The sorter user 4 clock cycles per word, but clock frequency may be |
much higher. |
/high_speed_pipelined_4clk_per_word/makefile
1,10 → 1,10
VHDLS = \ |
src/sys_config.vhd \ |
src/sorter_pkg.vhd \ |
src/dpram4.vhd \ |
src/dp_ram_scl_sorter_distributed.vhd \ |
src/dp_ram_scl_sorter.vhd \ |
src/dp_ram_scl_sorter_distributed.vhd \ |
src/sort_dpram.vhd \ |
src/sort_cmp_lt.vhd \ |
src/sorter_ctrl.vhd \ |
src/sorter_sys.vhd \ |
src/sorter_sys_tb.vhd \ |
30,7 → 30,7
ghdl -a --workdir=comp --std=${VSTD} --ieee=${STD} ${VHDLS} |
ghdl -e --workdir=comp --std=${VSTD} -fexplicit --ieee=${STD} ${ENTITY} |
events.out: ${ENTITY} events.in |
# ./${ENTITY} --wave=${ENTITY}.ghw ${RUN_OPTIONS} --stop-time=200000ns 2>&1 > res.txt |
# ./${ENTITY} --wave=${ENTITY}.ghw ${RUN_OPTIONS} --stop-time=50000ns 2>&1 > res.txt |
./${ENTITY} ${RUN_OPTIONS} 2>&1 > res.txt |
test: |
./sort_test_check.py |
/high_speed_pipelined_4clk_per_word/src/sorter_ctrl.vhd
6,7 → 6,7
-- Author : Wojciech M. Zabolotny <wzab@ise.pw.edu.pl> |
-- Company : |
-- Created : 2010-05-14 |
-- Last update: 2018-03-11 |
-- Last update: 2018-03-12 |
-- Platform : |
-- Standard : VHDL'93 |
------------------------------------------------------------------------------- |
306,6 → 306,30
end case; |
end process p1; |
|
sort_cmp_lt_1: entity work.sort_cmp_lt |
port map ( |
clk => clk, |
rst_n => rst_n, |
v1 => s_l_val_i, |
v2 => s_up_in_val, |
lt => res_sort_cmp_lt_l_up); |
|
sort_cmp_lt_2: entity work.sort_cmp_lt |
port map ( |
clk => clk, |
rst_n => rst_n, |
v1 => s_l_val_i, |
v2 => s_r_val_i, |
lt => res_sort_cmp_lt_l_r); |
|
sort_cmp_lt_3: entity work.sort_cmp_lt |
port map ( |
clk => clk, |
rst_n => rst_n, |
v1 => s_r_val_i, |
v2 => s_up_in_val, |
lt => res_sort_cmp_lt_r_up); |
|
p2 : process (clk) is |
begin -- process p2 |
if clk'event and clk = '1' then -- rising clock edge |
316,15 → 340,9
s_up_in_val <= DATA_REC_INIT_DATA; |
s_l_val <= DATA_REC_INIT_DATA; |
s_r_val <= DATA_REC_INIT_DATA; |
res_sort_cmp_lt_l_up <= false; |
res_sort_cmp_lt_l_r <= false; |
res_sort_cmp_lt_r_up <= false; |
--update_out <= '0'; |
--addr_out <= (others => '0'); |
else |
res_sort_cmp_lt_l_up <= sort_cmp_lt(s_l_val_i, s_up_in_val); |
res_sort_cmp_lt_l_r <= sort_cmp_lt(s_l_val_i, s_r_val_i); |
res_sort_cmp_lt_r_up <= sort_cmp_lt(s_r_val_i, s_up_in_val); |
s_ready_out <= s_ready_out_i; |
ctrl_state <= ctrl_state_next; |
addr <= addr_i; |
/high_speed_pipelined_4clk_per_word/src/sorter_pkg.vhd
6,7 → 6,7
-- Author : Wojciech M. Zabolotny <wzab@ise.pw.edu.pl> |
-- Company : |
-- Created : 2010-05-14 |
-- Last update: 2011-07-11 |
-- Last update: 2018-03-12 |
-- Platform : |
-- Standard : VHDL'93 |
------------------------------------------------------------------------------- |
69,11 → 69,6
); |
|
|
function sort_cmp_lt ( |
constant v1 : T_DATA_REC; |
constant v2 : T_DATA_REC) |
return boolean; |
|
function tdrec2stlv ( |
constant drec : T_DATA_REC) |
return std_logic_vector; |
129,71 → 124,6
end tdrec2stlv; |
|
|
-- Function sort_cmp_lt returns TRUE when the first opperand is ``less'' than |
-- the second one |
function sort_cmp_lt ( |
constant v1 : T_DATA_REC; |
constant v2 : T_DATA_REC) |
return boolean is |
variable rline : line; |
variable dcomp : unsigned(DATA_REC_SORT_KEY_WIDTH-1 downto 0) := (others => '0'); |
begin -- sort_cmp_lt |
-- Check the special cases |
if (v1.init = '1') and (v2.init = '0') then |
-- v1 is the special record, v2 is the standard one |
if v1.valid = '0' then |
-- initialization record - ``smaller'' than all standard records |
return true; |
else |
-- end record - ``bigger'' than all standard records |
return false; |
end if; |
elsif (v1.init = '0') and (v2.init = '1') then |
-- v2 is the special record, v1 is the standard one |
if (v2.valid = '0') then |
-- v2 is the initialization record - it is ``smaller'' than standard record v1 |
return false; |
else |
-- v2 is the end record - it is ``bigger'' than standard record v1 |
return true; |
end if; |
elsif (v1.init = '1') and (v2.init = '1') then |
-- both v1 and v2 are special records |
if (v1.valid = '0') and (v2.valid = '1') then |
-- v1 - initial record, v2 - end record |
return true; |
else |
-- v1 is end record, so it is ``bigger'' or ``equal'' to other records |
return false; |
end if; |
elsif (v1.init = '0') and (v2.init = '0') then |
-- We compare standard words |
-- We must consider the fact, that in longer sequences of data records |
-- the sort keys may wrap around |
-- therefore we perform subtraction modulo |
-- 2**DATA_REC_SORT_KEY_WIDTH and check the MSB |
dcomp := v1.d_key-v2.d_key; |
if dcomp(DATA_REC_SORT_KEY_WIDTH-1) = '1' then |
--if signed(v1.d_key - v2.d_key)<0 then -- old implementation |
return true; |
elsif v2.d_key = v1.d_key then |
if v2.valid = '1' then |
return true; |
else |
-- Empty data records should wait |
return false; |
end if; |
else |
return false; |
end if; |
else |
--assert false report "Wrong records in sort_cmp_lt" severity error; |
return false; |
end if; |
return false; -- should never happen |
end sort_cmp_lt; |
|
|
--procedure wrstlv ( |
-- rline : inout string; |
-- constant vect : std_logic_vector) is |