Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
9 years ago

VHDL help for using built in Comparators

Hi all,

when I try to use Quartus built in integer comparators I am experiencing some problem. I am trying to sort 64 numbers stored in a 2 port RAM. When I input the addresses and get back 2 integers, then I send these 2 integers into the built in comparator. The compare result is showing in next rising edge of the clock, but when I try to use IF statement to choose the small numbers, it seems that the comparing result detected is for last pairs. Can anyone help? Many thanks for the help.

The simulation result shows as follows:

http://www.alteraforum.com/forum/attachment.php?attachmentid=13213&stc=1


    ------------- send address to m1 to get number ---------------------
if (rd_adr_a < 62) then
    m1_rden_a <= '1';
    m1_rden_b <= '1';
    m1_wren_a <= '0';
    m1_wren_b <= '0';
    m1_adr_a <= std_logic_vector(to_unsigned(rd_adr_a, 7));
    m1_adr_b <= std_logic_vector(to_unsigned(rd_adr_b, 7));
    rd_adr_a := rd_adr_a + 2;
    rd_adr_b := rd_adr_b + 2;
else
    m1_rden_a <= '0';
    m1_rden_b <= '0';
end if;
    -------------- get m1 feedback, compare, and store to m2 ------------------                    
if (wr_adr_small < 62) then
    if (rd_delay < 3) then -- 3 clock cycle delay to wait m1 send back data
        rd_delay := rd_delay + 1;
    else
        cp_dataa <= m1_q_a;
        cp_datab <= m1_q_b;
        if (cp_delay < 1) then -- 1 cc omparator delay to wait comparator give result
            cp_delay := cp_delay + 1;
        else
            if (cp_eq = '1') then
                m2_rden_a <= '0';
                m2_rden_b <= '0';
                m2_wren_a <= '1';
                m2_wren_b <= '1';
                m2_data_a <= cp_dataa;
                m2_data_b <= cp_datab;
                m2_adr_a  <= std_logic_vector(to_unsigned(wr_adr_small, 7));
                m2_adr_b  <= std_logic_vector(to_unsigned(wr_adr_big, 7));
                wr_adr_small := wr_adr_small + 2;
                wr_adr_big   := wr_adr_big + 2;
            elsif (cp_gr = '1') then -- q_a > q_b
                m2_rden_a <= '0';
                m2_rden_b <= '0';
                m2_wren_a <= '1';
                m2_wren_b <= '1';
                m2_data_a <= cp_datab;
                m2_data_b <= cp_dataa;
                m2_adr_a  <= std_logic_vector(to_unsigned(wr_adr_small, 7));
                m2_adr_b  <= std_logic_vector(to_unsigned(wr_adr_big, 7));
                wr_adr_small := wr_adr_small + 2;
                wr_adr_big   := wr_adr_big + 2;
            elsif (cp_ls = '1') then -- q_a < q_b
                m2_rden_a <= '0';
                m2_rden_b <= '0';
                m2_wren_a <= '1';
                m2_wren_b <= '1';
                m2_data_a <= cp_dataa;
                m2_data_b <= cp_datab;
                m2_adr_a  <= std_logic_vector(to_unsigned(wr_adr_small, 7));
                m2_adr_b  <= std_logic_vector(to_unsigned(wr_adr_big, 7));
                wr_adr_small := wr_adr_small + 2;
                wr_adr_big   := wr_adr_big + 2;
            else
            
            end if;
        end if; -- end delay1cc
    end if; -- end delay3cc        
end if;

3 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I don't quite understand what the issue is. Are you saying the result should be put into mem2 on the same clock cycle as the comparison instead of the next cycle? It would help to see your PROCESS commands and sensitivity list assuming this is all synchronous to a clock.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks for the help.

    I mean the comparison result select data to the corresponding port of mem2. Let's say I input the two numbers, which coming out from mem1, into comparator at clock cycle 1. Then the comparison result will come out at clock cycle 2. And I use IF statement to choose the smaller number and send it to port_a at clock cycle 2. But what the IF statement has picked is the comparison result at clock cycle 1 but not clock cycle 2.

    The process is like follows:

    
    merg: PROCESS (clock, merg_en)
    -------------------------
    ---some variables ----
    -------------------------
    IF (rising_edge(clock)) then
         IF (merg_en = '1') then
                ------------- send address to m1 to get number ---------------------
                if (rd_adr_a < 62) then
                m1_rden_a <= '1';
                m1_rden_b <= '1';
                m1_wren_a <= '0';
                m1_wren_b <= '0';
                m1_adr_a <= std_logic_vector(to_unsigned(rd_adr_a, 7));
                m1_adr_b <= std_logic_vector(to_unsigned(rd_adr_b, 7));
                rd_adr_a := rd_adr_a + 2;
                rd_adr_b := rd_adr_b + 2;
            else
                m1_rden_a <= '0';
                m1_rden_b <= '0';
            end if;
                -------------- get m1 feedback, compare, and store to m2 ------------------                    
            if (wr_adr_small < 62) then
                if (rd_delay < 3) then -- 3 clock cycle delay to wait m1 send back data
                    rd_delay := rd_delay + 1;
                else
                    cp_dataa <= m1_q_a;
                    cp_datab <= m1_q_b;
                    if (cp_delay < 1) then -- 1 cc omparator delay to wait comparator give result
                        cp_delay := cp_delay + 1;
                    else
                        if (cp_eq = '1') then
                            m2_rden_a <= '0';
                            m2_rden_b <= '0';
                            m2_wren_a <= '1';
                            m2_wren_b <= '1';
                            m2_data_a <= cp_dataa;
                            m2_data_b <= cp_datab;
                            m2_adr_a  <= std_logic_vector(to_unsigned(wr_adr_small, 7));
                            m2_adr_b  <= std_logic_vector(to_unsigned(wr_adr_big, 7));
                            wr_adr_small := wr_adr_small + 2;
                            wr_adr_big   := wr_adr_big + 2;
                        elsif (cp_gr = '1') then -- q_a > q_b
                            m2_rden_a <= '0';
                            m2_rden_b <= '0';
                            m2_wren_a <= '1';
                            m2_wren_b <= '1';
                            m2_data_a <= cp_datab;
                            m2_data_b <= cp_dataa;
                            m2_adr_a  <= std_logic_vector(to_unsigned(wr_adr_small, 7));
                            m2_adr_b  <= std_logic_vector(to_unsigned(wr_adr_big, 7));
                            wr_adr_small := wr_adr_small + 2;
                            wr_adr_big   := wr_adr_big + 2;
                        elsif (cp_ls = '1') then -- q_a < q_b
                            m2_rden_a <= '0';
                            m2_rden_b <= '0';
                            m2_wren_a <= '1';
                            m2_wren_b <= '1';
                            m2_data_a <= cp_dataa;
                            m2_data_b <= cp_datab;
                            m2_adr_a  <= std_logic_vector(to_unsigned(wr_adr_small, 7));
                            m2_adr_b  <= std_logic_vector(to_unsigned(wr_adr_big, 7));
                            wr_adr_small := wr_adr_small + 2;
                            wr_adr_big   := wr_adr_big + 2;
            
                        else
                
                        end if;
                    end if; -- end delay1cc
                end if; -- end delay3cc        
            end if; -- end rd_adr_a
        end if; -- end merg_en
    ----------------------------------------
    -------- some other things ----------
    ----------------------------------------
    end if;
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Please can you clarify what you mean - maybe highlight the problem lines or make the code example smaller. Your question is not clear