Автор |
Сообщение |
|
|
Заголовок сообщения: |
Re: Делитель на VHDL |
|
|
А... ну тогда получается - b / a - "нижнее делить на верхнее", а я привел свой вариант к a / b потому оно и показалось перепутанным
А... ну тогда получается - b / a - "нижнее делить на верхнее", а я привел свой вариант к a / b потому оно и показалось перепутанным ;)
|
|
|
|
Добавлено: Пн янв 02, 2012 17:04 |
|
|
|
|
|
Заголовок сообщения: |
Re: Делитель на VHDL |
|
|
WingLion писал(а): кажется, что a и b операнды перепутаны... судя по коду... Да нет, вроде все правильно. Dqa у меня вершина стека, Dqb второе сверху. Второе делится на верхнее. По тексту вроде бы все правильно, тем более что оно в железе работает.
[quote="WingLion"]кажется, что a и b операнды перепутаны... судя по коду...[/quote] Да нет, вроде все правильно. Dqa у меня вершина стека, Dqb второе сверху. Второе делится на верхнее. По тексту вроде бы все правильно, тем более что оно в железе работает.
|
|
|
|
Добавлено: Пн янв 02, 2012 16:46 |
|
|
|
|
|
Заголовок сообщения: |
Re: Делитель на VHDL |
|
|
Хищник писал(а): Вроде бы так и делалось. Неужели я старую версию забрал?... в строчках: Код: when 0 => diva <= ext(Dqb, 64); divb <= Dqa & ext("0", 64 - DATAWIDTH); кажется, что a и b операнды перепутаны... судя по коду...
[quote="Хищник"]Вроде бы так и делалось. Неужели я старую версию забрал?...[/quote]
в строчках: [code] when 0 => diva <= ext(Dqb, 64); divb <= Dqa & ext("0", 64 - DATAWIDTH);[/code]
кажется, что a и b операнды перепутаны... судя по коду...
|
|
|
|
Добавлено: Пн янв 02, 2012 16:41 |
|
|
|
|
|
Заголовок сообщения: |
Re: Делитель на VHDL |
|
|
WingLion писал(а): dqa, dqb в ветке when 0 => поменял местами (чтобы dqb / dqa) получалось. формально - это делать незачем. Вроде бы так и делалось. Неужели я старую версию забрал?... WingLion писал(а): кстати, кажется, что позволять "делилке" работать лучше не только во время NOP-a, но и во время работы большинства других команд, тогда можно делать что-то параллельно работе "делилки" Впрочем, и загрузка результата деления в стек может стать поводом для вставки вайтов во время исполнения. А запускать ее всякий раз, как в стеке поменялись данные, тогда можно продолжать делить, пока что-то делается мимо стека... и потом, при загрузке результата, добить вайтами, если тактов не хватило. В принципе да, можно. Можно операнды разместить в адресном пространстве, и работать с делилкой через порты ВВ, это тоже вариант. Мне еще было интересно, насколько удобно окажется работать с системными регистрами (сейчас DEPTH, RDEPTH, I, частное, остаток, куча таймеров помещаются на стек через N SYSREG@). Сейчас при увеличении мультиплексируемых шин частота не падает. Но выделять "системный порт" как-то не хочется, а опкодов уже не осталось.
[quote="WingLion"]dqa, dqb в ветке when 0 => поменял местами (чтобы dqb / dqa) получалось. формально - это делать незачем.[/quote] Вроде бы так и делалось. Неужели я старую версию забрал?... [quote="WingLion"]кстати, кажется, что позволять "делилке" работать лучше не только во время NOP-a, но и во время работы большинства других команд, тогда можно делать что-то параллельно работе "делилки" Впрочем, и загрузка результата деления в стек может стать поводом для вставки вайтов во время исполнения. А запускать ее всякий раз, как в стеке поменялись данные, тогда можно продолжать делить, пока что-то делается мимо стека... и потом, при загрузке результата, добить вайтами, если тактов не хватило.[/quote] В принципе да, можно. Можно операнды разместить в адресном пространстве, и работать с делилкой через порты ВВ, это тоже вариант. Мне еще было интересно, насколько удобно окажется работать с системными регистрами (сейчас DEPTH, RDEPTH, I, частное, остаток, куча таймеров помещаются на стек через N SYSREG@). Сейчас при увеличении мультиплексируемых шин частота не падает. Но выделять "системный порт" как-то не хочется, а опкодов уже не осталось.
|
|
|
|
Добавлено: Пн янв 02, 2012 15:15 |
|
|
|
|
|
Заголовок сообщения: |
Re: Делитель на VHDL |
|
|
Доковырял по логике, заменил ext() на то, что показалось правильным, получилось: Код: LIBRARY IEEE; USE IEEE.std_logic_1164.all; USE IEEE.std_logic_unsigned.all; USE WORK.Common_lib.all; ENTITY TEST_DIV IS
Port( clk : in node; dqa,dqb : in dword; rdiv,rrem : out dword; cmd : in std_logic_vector (5 downto 0)
); end TEST_DIV; architecture rtl of TEST_DIV is signal divst : integer range 0 to 63; signal wdiv : dword; -- std_logic_vector (63 downto 0); signal diva,divb : qword; --std_logic_vector (63 downto 0);
constant zero32 : dword := (others => '0'); begin
process(clk) begin if rising_edge(clk) then case divst is when 0 => diva <= zero32 & dqa; divb <= Dqb & zero32; wdiv <= zero32; divst <= 1; when 1 to 33 => if cmd = "000000" then if diva >= divb then wdiv <= wdiv(30 downto 0) & '1'; diva <= diva - divb; else wdiv <= wdiv(30 downto 0) & '0'; end if; divb <= '0' & divb(63 downto 1); divst <= divst + 1; else divst <= 0; end if; when 34 => rdiv <= wdiv(31 downto 0); rrem <= diva(31 downto 0); divst <= 0; when others => divst <= 0; end case; end if; end process;
end; И даже откомпилилось в Quartus... И даже отсимулировалось... 1000 / 100 = 10 (0) 1000 / 120 = 8 (40) dqa, dqb в ветке when 0 => поменял местами (чтобы dqb / dqa) получалось. формально - это делать незачем. На циклоне2 - 98 MHz (409 LCELL) на циклоне3 - 107 MHz (410 LCELL) кстати, кажется, что позволять "делилке" работать лучше не только во время NOP-a, но и во время работы большинства других команд, тогда можно делать что-то параллельно работе "делилки" Впрочем, и загрузка результата деления в стек может стать поводом для вставки вайтов во время исполнения. А запускать ее всякий раз, как в стеке поменялись данные, тогда можно продолжать делить, пока что-то делается мимо стека... и потом, при загрузке результата, добить вайтами, если тактов не хватило.
Доковырял по логике, заменил ext() на то, что показалось правильным, получилось:
[code]LIBRARY IEEE; USE IEEE.std_logic_1164.all; USE IEEE.std_logic_unsigned.all; USE WORK.Common_lib.all; ENTITY TEST_DIV IS
Port( clk : in node; dqa,dqb : in dword; rdiv,rrem : out dword; cmd : in std_logic_vector (5 downto 0)
); end TEST_DIV; architecture rtl of TEST_DIV is signal divst : integer range 0 to 63; signal wdiv : dword; -- std_logic_vector (63 downto 0); signal diva,divb : qword; --std_logic_vector (63 downto 0);
constant zero32 : dword := (others => '0'); begin
process(clk) begin if rising_edge(clk) then case divst is when 0 => diva <= zero32 & dqa; divb <= Dqb & zero32; wdiv <= zero32; divst <= 1; when 1 to 33 => if cmd = "000000" then if diva >= divb then wdiv <= wdiv(30 downto 0) & '1'; diva <= diva - divb; else wdiv <= wdiv(30 downto 0) & '0'; end if; divb <= '0' & divb(63 downto 1); divst <= divst + 1; else divst <= 0; end if; when 34 => rdiv <= wdiv(31 downto 0); rrem <= diva(31 downto 0); divst <= 0; when others => divst <= 0; end case; end if; end process;
end;[/code]
И даже откомпилилось в Quartus... И даже отсимулировалось... 1000 / 100 = 10 (0) 1000 / 120 = 8 (40)
dqa, dqb в ветке when 0 => поменял местами (чтобы dqb / dqa) получалось. формально - это делать незачем.
На циклоне2 - 98 MHz (409 LCELL) на циклоне3 - 107 MHz (410 LCELL)
кстати, кажется, что позволять "делилке" работать лучше не только во время NOP-a, но и во время работы большинства других команд, тогда можно делать что-то параллельно работе "делилки" ;) Впрочем, и загрузка результата деления в стек может стать поводом для вставки вайтов во время исполнения. А запускать ее всякий раз, как в стеке поменялись данные, тогда можно продолжать делить, пока что-то делается мимо стека... и потом, при загрузке результата, добить вайтами, если тактов не хватило.
|
|
|
|
Добавлено: Пн янв 02, 2012 05:00 |
|
|
|
|
|
Заголовок сообщения: |
Re: Делитель на VHDL |
|
|
Решил попробовать в Quartusе После объявления всех входных, внутренних и выходных сигналов: Код: LIBRARY IEEE; USE IEEE.std_logic_1164.all; USE IEEE.std_logic_unsigned.all; USE WORK.Common_lib.all; ENTITY TEST_DIV IS
Port( clk : in node; dqa,dqb : in dword; rdiv,rrem : out dword; cmd : in std_logic_vector (5 downto 0)
); end TEST_DIV; architecture rtl of TEST_DIV is signal divst : integer range 0 to 63; signal wdiv : qword; -- std_logic_vector (63 downto 0); signal diva,divb : qword; --std_logic_vector (63 downto 0); begin
process(clk) begin if rising_edge(clk) then case divst is when 0 => diva <= ext(Dqb, 64); divb <= Dqa & ext("0", 64 - DATAWIDTH); wdiv <= (others => '0'); divst <= 1; when 1 to 33 => if cmd = "000000" then if diva >= divb then wdiv <= wdiv(30 downto 0) & '1'; diva <= diva - divb; else wdiv <= wdiv(30 downto 0) & '0'; end if; divb <= '0' & divb(63 downto 1); divst <= divst + 1; else divst <= 0; end if; when 34 => rdiv <= wdiv(31 downto 0); rrem <= diva(31 downto 0); divst <= 0; when others => divst <= 0; end case; end if; end process;
end; Quartus выдает: Цитата: Error (.....): object "ext" is used but not declared не совсем понятно, что эта функция делает, чтобы ее в common_lib.vhd внести
Решил попробовать в Quartusе После объявления всех входных, внутренних и выходных сигналов:
[code] LIBRARY IEEE; USE IEEE.std_logic_1164.all; USE IEEE.std_logic_unsigned.all; USE WORK.Common_lib.all; ENTITY TEST_DIV IS
Port( clk : in node; dqa,dqb : in dword; rdiv,rrem : out dword; cmd : in std_logic_vector (5 downto 0)
); end TEST_DIV; architecture rtl of TEST_DIV is signal divst : integer range 0 to 63; signal wdiv : qword; -- std_logic_vector (63 downto 0); signal diva,divb : qword; --std_logic_vector (63 downto 0); begin
process(clk) begin if rising_edge(clk) then case divst is when 0 => diva <= ext(Dqb, 64); divb <= Dqa & ext("0", 64 - DATAWIDTH); wdiv <= (others => '0'); divst <= 1; when 1 to 33 => if cmd = "000000" then if diva >= divb then wdiv <= wdiv(30 downto 0) & '1'; diva <= diva - divb; else wdiv <= wdiv(30 downto 0) & '0'; end if; divb <= '0' & divb(63 downto 1); divst <= divst + 1; else divst <= 0; end if; when 34 => rdiv <= wdiv(31 downto 0); rrem <= diva(31 downto 0); divst <= 0; when others => divst <= 0; end case; end if; end process;
end; [/code]
Quartus выдает:
[quote]Error (.....): object "ext" is used but not declared[/quote]
не совсем понятно, что эта функция делает, чтобы ее в common_lib.vhd внести
|
|
|
|
Добавлено: Пн янв 02, 2012 04:36 |
|
|
|
|
|
Заголовок сообщения: |
Делитель на VHDL |
|
|
Делилка. Работает, когда процессор делает NOP в цикле. Когда не NOP, откатывается на нулевое состояние. Через 34 такта в выходные регистры сбрасывается частное и остаток. Верифицировано (Spartan-6). Код: -- divider
process(clk) begin if rising_edge(clk) then case divst is when 0 => diva <= ext(Dqb, 64); divb <= Dqa & ext("0", 64 - DATAWIDTH); wdiv <= (others => '0'); divst <= 1; when 1 to 33 => if cmd = "000000" then if diva >= divb then wdiv <= wdiv(30 downto 0) & '1'; diva <= diva - divb; else wdiv <= wdiv(30 downto 0) & '0'; end if; divb <= '0' & divb(63 downto 1); divst <= divst + 1; else divst <= 0; end if; when 34 => rdiv <= wdiv(31 downto 0); rrem <= diva(31 downto 0); divst <= 0; when others => divst <= 0; end case; end if; end process;
Делилка. Работает, когда процессор делает NOP в цикле. Когда не NOP, откатывается на нулевое состояние. Через 34 такта в выходные регистры сбрасывается частное и остаток. Верифицировано (Spartan-6). [code]-- divider
process(clk) begin if rising_edge(clk) then case divst is when 0 => diva <= ext(Dqb, 64); divb <= Dqa & ext("0", 64 - DATAWIDTH); wdiv <= (others => '0'); divst <= 1; when 1 to 33 => if cmd = "000000" then if diva >= divb then wdiv <= wdiv(30 downto 0) & '1'; diva <= diva - divb; else wdiv <= wdiv(30 downto 0) & '0'; end if; divb <= '0' & divb(63 downto 1); divst <= divst + 1; else divst <= 0; end if; when 34 => rdiv <= wdiv(31 downto 0); rrem <= diva(31 downto 0); divst <= 0; when others => divst <= 0; end case; end if; end process; [/code]
|
|
|
|
Добавлено: Пн янв 02, 2012 03:21 |
|
|
|
|