Jump to content
    

Определение 1/6 числа

Приветствую!

1 hour ago, Serhiy_UA said:

Экономно получилось!

Получилось что?

 

Удачи! Rob.

Share this post


Link to post
Share on other sites

3 часа назад, RobFPGA сказал:

Приветствую!

Получилось что?

Удачи! Rob.

Решить исходную задачу ТС. Ведь задача такова что применять деление как таковое совсем не обязательно.

Share this post


Link to post
Share on other sites

Приветствую!

19 minutes ago, _sda said:

Решить исходную задачу ТС. Ведь задача такова что применять деление как таковое совсем не обязательно.

Ну это было еще  не решение  а лишь  часть его, и отнюдь  не экономное.

 

Удачи! Rob. 

Share this post


Link to post
Share on other sites

40 минут назад, RobFPGA сказал:

Приветствую!

Ну это было еще  не решение  а лишь  часть его, и отнюдь  не экономное.

 

Удачи! Rob. 

ТС предложили вариант, думаю что остальное он сам допилит. Не нужно лишать его удовольствия предлагая решение сразу всей задачи.

Share this post


Link to post
Share on other sites

7 часов назад, Serhiy_UA сказал:

Экономно получилось!

Может, вместо

count2 <= 0;

правильнее

count2 <= count2 - count1;

?

Share this post


Link to post
Share on other sites

31 minutes ago, adnega said:

Может, вместо


count2 <= 0;

правильнее


count2 <= count2 - count1;

 

правильнее, но там ТС что-то про про экономию ресурсов говорил, а про правильное округление - нет.

тем более что у него 487/6 = 81.1666 это 82.

Share this post


Link to post
Share on other sites

1 час назад, _pv сказал:

правильнее, но там ТС что-то про про экономию ресурсов говорил, а про правильное округление - нет.

тем более что у него 487/6 = 81.1666 это 82.

Неделю назад делал эмулятор советских УМС на тини10 по этому алгоритму.

Не думаю, что для FPGA вычитание числа будет существенной растратой ресурсов, только если там не тысячи подобных каналов и/или не огромные частоты работы.

Share this post


Link to post
Share on other sites

08.04.2021 в 20:25, _sda сказал:

Решить исходную задачу ТС. Ведь задача такова что применять деление как таковое совсем не обязательно.

Это деление в столбик.  Для 16-ти разрядного числа, за 14 тактов.

    
    sub <= res - x"60000";     
    
    process(clk,rst)      
    begin
        if rst = '1' then  
            res <= (others => '0');     
            cnt <= x"0";
        elsif clk = '1' and clk'event then    
            if str = '1' then res <= '0' & div & "000"; 
            elsif cnt /= 0 then 
                if sub(19) = '1' then res <= res(18 downto 0) & '0'; 
                else                  res <= sub(18 downto 0) & '1';
                end if;                
            end if;    
            if str = '1' then cnt <= x"e";  elsif cnt /= 0 then cnt <= cnt - 1;   end if;
        end if;
        
    end process;

В младших разрядах частное , в старших остаток. 

 

Share this post


Link to post
Share on other sites

On 4/8/2021 at 9:04 AM, Valek87 said:

Здравствуйте.

У меня есть 2 счетчика.  Значение первого счетчика (count1) после определенного события запоминается. Например, это значение = 487. Теперь второй счетчик (count2) должен генерировать каждые 1/6*count1 (т.е. 487/6 ~ 82) тактов сигнал готовности. У меня вопрос - как мне определить эту 1/6 часть значения от count1? Спасибо.

есть 2 счетчика.  Значение первого счетчика (count1) после определенного события (inp_event) запоминается, второй счетчик (count2) должен генерировать каждые 1/6*count1  тактов сигнал готовности (out_en)

для начала требуется написать логику работы первого счетчика (count1), тут он просто со сбросом по резету (reset)

always @(posedge clk)
begin
    if (reset)
    begin
        count1 <= 0;
    end
    else
    begin
        count1 <= count1 + 1;
    end
end

для второго счетчика (count2) требуется отсчитать 1/6 от первого счетчика (count1), такое значение будет отсчитывать отдельный счетчик (count1_divby_6), отдельный счетчик (count1_divby_6) будет вести отсчет в шесть раз медленнее, по сигналу (cnt6_eq_1)

сигнал (cnt6_eq_1) будет формироваться вспомогательным счетчиком (cnt6), который будет отсчитывать по 6 тактов

always @(posedge clk)
begin
    if (reset)
    begin
        cnt6 <= 0;
        cnt6_eq_1 <= 0;
        count1_divby_6 <= 0;
    end
    else
    begin
        cnt6 <= cnt6 + 1;
        if (cnt6==5)
        begin
            cnt6 <= 0;
        end
        cnt6_eq_1 <= (cnt6==1);
        if(cnt6_eq_1)
        begin
            count1_divby_6 <= count1_divby_6 + 1;
        end
    end
end

идея добавления отдельного счетчика (count1_divby_6) состоит в том, что пока первый счетчик (count1) отсчитывает 0,1,2,3,4,5,6,7,8,9 и т.д., вспомогательный счетчик (cnt6) отсчитывает 0,1,2,3,4,5,0,1,2,3 и т.д., отдельный счетчик (count1_divby_6) отсчитывает 0,0,0,1,1,1,1,1,1,2, и т.д., то есть значение отдельного счетчика (count1_divby_6) отсчитываются как 1/6 от первого счетчика (count1), причем значение отдельного счетчика (count1_divby_6) сразу округлено до ближайшего целого

примерно вот так:

count1        : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18 ...
cnt6          : 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0 ...
cnt6_eq_1     : 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ...
count1_divby_6: 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3 ...

 

после определенного события (inp_event) при запоминании значения от первого счетчика (count1_event_val),
запоминаем и значение, деленное на 6 (count1_divby_6_event_val)

always @(posedge clk)
begin
    if (reset)
    begin
        count1_event_val <= 0;
        count1_divby_6_event_val <= 0;
    end
    else if (inp_event)
    begin
        count1_event_val <= count1;
        count1_divby_6_event_val <= count1_divby_6;
    end
end

второй счетчик (count2) не должен считать до определенного события (inp_event),
а значит нужно сформировать сигнал (inp_event_done),
определяющий, произошло ли уже определенное событие (inp_event)

always @(posedge clk)
begin
    if (reset)
    begin
        inp_event_done <= 0;
    end
    else if (inp_event)
    begin
        inp_event <= 1;
    end
end

далее для второго счетчика (count2) мы можем использовать значение, деленное на 6 (count1_divby_6_event_val)

always @(posedge clk)
begin
    if (reset)
    begin
        count2 <= 0;
        out_en <= 0;
    end
    else if (inp_event_done)
    begin
        count2 <= count2 + 1;
        out_en <= 0;
        if (count2==(count1_divby_6_event_val-1))
        begin
            count2 <= 0;
            out_en <= 1;
        end
    end
end

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...