TRILLER 0 22 октября, 2012 Опубликовано 22 октября, 2012 · Жалоба Была у меня похожая задача, на 100 МГц на циклоне 3 схема работала. ISK, не могли бы подробнее рассказать что к чему? Уже несколько часов потратил, никак не разберусь - толи устал, толи способностей не хватает( Переменной point_cnt вы что задаёте? Также меня интересует начальное состояние cmp_res... В зависимости от него в строке cmp_res_reg(15) независимо от add_sub_res будет либо X"8000" , либо X"FFFF"... Ничего не понимаю, объясните пожалуйста подробнее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TRILLER 0 23 октября, 2012 Опубликовано 23 октября, 2012 (изменено) · Жалоба Вобщем, с кодом ISKа разобраться так и не смог, сделал свой вариант. Если входной массив разбить по 4 слова, и использовать не сравнение значений, а разность(т.е. логику ускоренного переноса), то получается довольно неплохо. library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; library UNISIM; use UNISIM.VComponents.all; entity Sort_Four is generic( wigth : natural := 16); Port ( clk : in std_logic; in_word : in std_logic_vector((4*wigth - 1) downto 0); ---- out_index : out std_logic_vector(1 downto 0); out_data : out std_logic_vector((wigth - 1) downto 0)); end Sort_Four; architecture Behavioral of Sort_Four is ----------------------------------------------------------- ----------------------------------------------------------- attribute syn_hier : string; attribute syn_hier of Behavioral : architecture is "hard"; attribute syn_keep : boolean; ----------------------------------------------------------- ----------------------------------------------------------- type word_type is array (0 to 3) of std_logic_vector((wigth - 1) downto 0); signal word, word_1d : word_type; signal sub_0f : std_logic_vector(1 downto 0); signal word_mux_st, word_mux_ml : std_logic_vector((wigth - 1) downto 0); signal sub_1f : std_logic; signal sub_general : std_logic_vector(2 downto 0); -- signal data_1d, data : std_logic_vector((order - 1) downto 0); ----------------------------------------------------------- ----------------------------------------------------------- begin ----------------------------------------------------------- ----------------------------------------------------------- process (clk) begin if (clk = '1' and clk'event) then for i in 0 to 3 loop word_1d(i) <= in_word(((i + 1)*wigth - 1) downto i*wigth); word(i) <= word_1d(i); end loop; end if; end process; ----------------------------------------------------------- ----------------------------------------------------------- process (word) variable sub_w32_temp, sub_w10_temp : std_logic_vector((wigth - 1) downto 0); begin sub_w32_temp := (word(3) + (not word(2)) + 1); sub_w10_temp := (word(1) + (not word(0)) + 1); sub_0f <= (sub_w32_temp(wigth - 1)&sub_w10_temp(wigth - 1)); end process; word_mux_st <= word(3) when sub_0f(1) = '1' else word(2); word_mux_ml <= (not word(1)) when sub_0f(0) = '1' else (not word(0)); ----------------------------------------------------------- ----------------------------------------------------------- process (word_mux_st, word_mux_ml) variable word_mux_temp : std_logic_vector((wigth - 1) downto 0); begin word_mux_temp := (word_mux_st + word_mux_ml + 1); sub_1f <= word_mux_temp(wigth - 1); end process; ----------------------------------------------------------- ----------------------------------------------------------- -- process (clk) -- begin -- if (clk = '1' and clk'event) then -- if sub_1f = '1' then -- if sub_0f(1) = '1' then -- data_1d <= word(3); -- else -- data_1d <= word(2); -- end if; -- else -- if sub_0f(0) = '1' then -- data_1d <= word(1); -- else -- data_1d <= word(0); -- end if; -- end if; -- data <= data_1d; -- end if; -- end process; -- out_data <= data; ----------------------------------------------------------- ----------------------------------------------------------- sub_general <= (sub_1f&sub_0f); process (sub_general, word) begin case sub_general is when "000" => out_data <= word(0); out_index <= "00"; when "001" => out_data <= word(0); out_index <= "00"; when "010" => out_data <= word(1); out_index <= "01"; when "011" => out_data <= word(1); out_index <= "01"; when "100" => out_data <= word(2); out_index <= "10"; when "101" => out_data <= word(2); out_index <= "10"; when "110" => out_data <= word(3); out_index <= "11"; when "111" => out_data <= word(3); out_index <= "11"; when others => null; end case; end process; end Behavioral; При входном массиве 16x16 получается 8 слоёв логики(не считая carry-chain), и для V6-1 схема разводится на 185МГц... Жалко только, что мне надо 300 - буду ставить конвеер( Изменено 23 октября, 2012 пользователем TRILLER Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Corner 0 17 августа, 2013 Опубликовано 17 августа, 2013 · Жалоба Быстрый счетчик реализуется на нескольких сумматорах с зарегистренным переносом. Сложение по факту выполняется за несколько тактов. Я использовал 4 сумматора +1, +2, +3 и +4 от общего регистра, который обновляется раз в 4 такта от сумматора +4, а результаты сложений перебираются каждый такт мультиплексором. В результате получаешь счетчик работающий не в реальном времени, но собирающийся на частоте +30... 40 % к однопроходному. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
riza 0 11 мая, 2014 Опубликовано 11 мая, 2014 · Жалоба всем привет! учусь на втором курсе.задали сделать семестровую работу по теме: "Моделирование САУ Адаптивного робота:Проектирование в виде системы на кристалле или интегральная схема - на основе метода ПЛИС, используя VHDL..но я не знаю как(VHDL не проходили даже)...помогите пожалуйста! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 11 мая, 2014 Опубликовано 11 мая, 2014 · Жалоба всем привет! учусь на втором курсе.задали сделать семестровую работу по теме: "Моделирование САУ Адаптивного робота:Проектирование в виде системы на кристалле или интегральная схема - на основе метода ПЛИС, используя VHDL..но я не знаю как(VHDL не проходили даже)...помогите пожалуйста! 1. Написать алгоритм работы робота 2. По нему сделать блок-схему алгоритма 3. По ней сделать блок-схему вычислителя. 4. Проверить ее в маткадах-иатлабах 5. Вычислитель реализовать в ПЛИС... Вот собственно и все... Первые 4 пункта можно делать, ничего не зная о ПЛИС... Или мало зная о ПЛИС. Потом задать преподу вопрос: почему заставляют делать то, чему не учили... Мы готовы ответить на конкретный вопрос, но не делать за Вас всю работу. Нам это не интересно, это Ваша проблема, а не наша... Да и тему надо перенести в другой раздел.... Либо для "начинающих", либо "предлагаю работу".... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
riza 0 11 мая, 2014 Опубликовано 11 мая, 2014 · Жалоба спасибо большое! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
olgapet 0 28 мая, 2014 Опубликовано 28 мая, 2014 · Жалоба 2 вопроса: а) чем содержательно должен отличаться подразумеваемый раздел от 4-ого раздела по ПЛИС "Системы на ПЛИС - System on Programmable Chip" (он открывался для обсуждения корок)? большей мелкозернистостью обсуждаемых модулей? б) по какому принципу будет организовываться структура раздела? надеюсь каталогизация подразумевается? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
axalay 0 3 августа, 2015 Опубликовано 3 августа, 2015 · Жалоба может кому будет нужно `timescale 1ns / 1ps // module divider # ( parameter WIDTH_DIVIDENT = 27, parameter WIDTH_DIVIDER = 9 ) ( // global input Clock, // input input DivIn, input [WIDTH_DIVIDENT-1 : 0] Divident, input [WIDTH_DIVIDER-1 : 0] Divider, // output output wire DivOut, output wire [WIDTH_DIVIDENT-1 : 0] Result, output wire [WIDTH_DIVIDER-1 : 0] Fractional, // debug output wire Test ); // wire [0 : 0] Comp [WIDTH_DIVIDENT-1 : 0]; wire [WIDTH_DIVIDER-1 : 0] CarryTemp [WIDTH_DIVIDENT-1 : 0]; // sift registers reg [0 : 0] DivTemp [WIDTH_DIVIDENT-1 : 0]; reg [WIDTH_DIVIDENT-1 : 0] ResultTemp [WIDTH_DIVIDENT-1 : 0]; reg [WIDTH_DIVIDENT+WIDTH_DIVIDER-1 : 0] DividentTemp [WIDTH_DIVIDENT-1 : 0]; reg [WIDTH_DIVIDER-1 : 0] DividerTemp [WIDTH_DIVIDENT-1 : 0]; // first always @(posedge Clock) begin DivTemp[0][0 : 0] = DivIn; ResultTemp[0][WIDTH_DIVIDENT-1 : 0] = (Comp[0]) ? 8'd1 : 8'd0; DividentTemp[0][WIDTH_DIVIDENT+WIDTH_DIVIDER-2 : 0] = {{(WIDTH_DIVIDER-1){1'b0}}, Divident[WIDTH_DIVIDENT-1 : 0]}; DividerTemp[0][WIDTH_DIVIDER-1 : 0] = Divider[WIDTH_DIVIDER-1 : 0]; end //always // next all genvar i; generate for (i=1; i<WIDTH_DIVIDENT; i=i+1) begin: shift always @(posedge Clock) begin DivTemp[0 : 0] = DivTemp[i-1][0 : 0]; ResultTemp[WIDTH_DIVIDENT-1 : 0] = {(ResultTemp[i-1][WIDTH_DIVIDENT-2 : 0]), ((Comp) ? 1'b1 : 1'b0)}; DividentTemp[WIDTH_DIVIDENT+WIDTH_DIVIDER-2 : 0] = {CarryTemp[i-1][WIDTH_DIVIDER-2 : 0], DividentTemp[i-1][WIDTH_DIVIDENT-2 : 0], 1'b0}; DividerTemp[WIDTH_DIVIDER-1 : 0] = DividerTemp[i-1][WIDTH_DIVIDER-1 : 0]; end //always end endgenerate // calculate genvar j; generate for (j=0; j<WIDTH_DIVIDENT; j=j+1) begin: calc assign Comp[j][0 : 0] = (DividentTemp[j][WIDTH_DIVIDENT+WIDTH_DIVIDER-2 :WIDTH_DIVIDENT-1] >= DividerTemp[j][WIDTH_DIVIDER-1 : 0]) ? 1'b1 : 1'b0; assign CarryTemp[j][WIDTH_DIVIDER-1 : 0] = (Comp[j]) ? (DividentTemp[j][WIDTH_DIVIDENT+WIDTH_DIVIDER-2 :WIDTH_DIVIDENT-1] - DividerTemp[j][WIDTH_DIVIDER-1 : 0]) : DividentTemp[j][WIDTH_DIVIDENT+WIDTH_DIVIDER-2 :WIDTH_DIVIDENT-1]; end endgenerate // fractional reg [WIDTH_DIVIDER-1 : 0] FractionalReg; always @(posedge Clock) FractionalReg[WIDTH_DIVIDER-1 : 0] = CarryTemp[WIDTH_DIVIDENT-1]; // result valid reg DivReg; always @(posedge Clock) DivReg = DivTemp[WIDTH_DIVIDENT-1][0 : 0]; // output assign Result[WIDTH_DIVIDENT-1 : 0] = ResultTemp[WIDTH_DIVIDENT-1]; assign Fractional[WIDTH_DIVIDER-1 : 0] = FractionalReg[WIDTH_DIVIDER-1 : 0]; assign DivOut = DivReg; // debug assign Test = 1'b0; endmodule //divider Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
serjj1333 0 3 августа, 2015 Опубликовано 3 августа, 2015 · Жалоба может кому будет нужно ... Оформите в виде исходного файла + простенького тб в архиве блоки // next all ... // calculate ... имхо лучше сделать как обычные циклы под always@(posedge Clock) и always@(*) соответственно ну и если вруг не лениво, то небольшую справку по результатам имплементации на любой понравившейся ПЛИС, чтобы человек, если вдруг заинтересуется, имел представление во что это ему может вылиться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
axalay 0 3 августа, 2015 Опубликовано 3 августа, 2015 · Жалоба вот другая реализация. Это простые делители - первый итерационный, а этот нет // Fast Array Divider 8 bit to 4 bit module fast_array_divider (a_in, d_in, q_out, r_out); input [7:0] a_in; input [3:0] d_in; output [7:0] q_out; wire [7:0] q_out; output [3:0] r_out; wire [3:0] r_out; wire [12:1] a; wire [4:1] d; wire [8:1] q; wire [8:5] r; wire c_0_3, c_0_2, c_0_1, c_0_0; wire s_0_3, s_0_2, s_0_1, s_0_0; wire q1_inv; restoring_array_divider array_0_0 ( a[2], d[1], c_0_1, q1_inv, c_0_0, s_0_0); restoring_array_divider array_0_1 ( a[3], d[2], c_0_2, q1_inv, c_0_1, s_0_1); restoring_array_divider array_0_2 ( a[4], d[3], c_0_3, q1_inv, c_0_2, s_0_2); restoring_array_divider array_0_3 ( a[5], d[4], 1'b0, q1_inv, c_0_3, s_0_3); assign q[1] = ( a[1] | !c_0_0 ); assign q1_inv=!q[1]; wire c_1_3, c_1_2, c_1_1, c_1_0; wire s_1_3, s_1_2, s_1_1, s_1_0; wire q2_inv; restoring_array_divider array_1_0 ( s_0_1, d[1], c_1_1, q2_inv, c_1_0, s_1_0); restoring_array_divider array_1_1 ( s_0_2, d[2], c_1_2, q2_inv, c_1_1, s_1_1); restoring_array_divider array_1_2 ( s_0_3, d[3], c_1_3, q2_inv, c_1_2, s_1_2); restoring_array_divider array_1_3 ( a[6], d[4], 1'b0, q2_inv, c_1_3, s_1_3); assign q[2] = ( s_0_0 | !c_1_0 ); assign q2_inv=!q[2]; wire c_2_3, c_2_2, c_2_1, c_2_0; wire s_2_3, s_2_2, s_2_1, s_2_0; wire q3_inv; restoring_array_divider array_2_0 ( s_1_1, d[1], c_2_1, q3_inv, c_2_0, s_2_0); restoring_array_divider array_2_1 ( s_1_2, d[2], c_2_2, q3_inv, c_2_1, s_2_1); restoring_array_divider array_2_2 ( s_1_3, d[3], c_2_3, q3_inv, c_2_2, s_2_2); restoring_array_divider array_2_3 ( a[7], d[4], 1'b0, q3_inv, c_2_3, s_2_3); assign q[3] = ( s_1_0 | !c_2_0 ); assign q3_inv=!q[3]; wire c_3_3, c_3_2, c_3_1, c_3_0; wire s_3_3, s_3_2, s_3_1, s_3_0; wire q4_inv; restoring_array_divider array_3_0 ( s_2_1, d[1], c_3_1, q4_inv, c_3_0, s_3_0); restoring_array_divider array_3_1 ( s_2_2, d[2], c_3_2, q4_inv, c_3_1, s_3_1); restoring_array_divider array_3_2 ( s_2_3, d[3], c_3_3, q4_inv, c_3_2, s_3_2); restoring_array_divider array_3_3 ( a[8], d[4], 1'b0, q4_inv, c_3_3, s_3_3); assign q[4] = ( s_2_0 | !c_3_0 ); assign q4_inv=!q[4]; wire c_4_3, c_4_2, c_4_1, c_4_0; wire s_4_3, s_4_2, s_4_1, s_4_0; wire q5_inv; restoring_array_divider array_4_0 ( s_3_1, d[1], c_4_1, q5_inv, c_4_0, s_4_0); restoring_array_divider array_4_1 ( s_3_2, d[2], c_4_2, q5_inv, c_4_1, s_4_1); restoring_array_divider array_4_2 ( s_3_3, d[3], c_4_3, q5_inv, c_4_2, s_4_2); restoring_array_divider array_4_3 ( a[9], d[4], 1'b0, q5_inv, c_4_3, s_4_3); assign q[5] = ( s_3_0 | !c_4_0 ); assign q5_inv=!q[5]; wire c_5_3, c_5_2, c_5_1, c_5_0; wire s_5_3, s_5_2, s_5_1, s_5_0; wire q6_inv; restoring_array_divider array_5_0 ( s_4_1, d[1], c_5_1, q6_inv, c_5_0, s_5_0); restoring_array_divider array_5_1 ( s_4_2, d[2], c_5_2, q6_inv, c_5_1, s_5_1); restoring_array_divider array_5_2 ( s_4_3, d[3], c_5_3, q6_inv, c_5_2, s_5_2); restoring_array_divider array_5_3 ( a[10], d[4], 1'b0, q6_inv, c_5_3, s_5_3); assign q[6] = ( s_4_0 | !c_5_0 ); assign q6_inv=!q[6]; wire c_6_3, c_6_2, c_6_1, c_6_0; wire s_6_3, s_6_2, s_6_1, s_6_0; wire q7_inv; restoring_array_divider array_6_0 ( s_5_1, d[1], c_6_1, q7_inv, c_6_0, s_6_0); restoring_array_divider array_6_1 ( s_5_2, d[2], c_6_2, q7_inv, c_6_1, s_6_1); restoring_array_divider array_6_2 ( s_5_3, d[3], c_6_3, q7_inv, c_6_2, s_6_2); restoring_array_divider array_6_3 ( a[11], d[4], 1'b0, q7_inv, c_6_3, s_6_3); assign q[7] = ( s_5_0 | !c_6_0 ); assign q7_inv=!q[7]; wire c_7_3, c_7_2, c_7_1, c_7_0; wire s_7_3, s_7_2, s_7_1, s_7_0; wire q8_inv; restoring_array_divider array_7_0 ( s_6_1, d[1], c_7_1, q8_inv, c_7_0, s_7_0); restoring_array_divider array_7_1 ( s_6_2, d[2], c_7_2, q8_inv, c_7_1, s_7_1); restoring_array_divider array_7_2 ( s_6_3, d[3], c_7_3, q8_inv, c_7_2, s_7_2); restoring_array_divider array_7_3 ( a[12], d[4], 1'b0, q8_inv, c_7_3, s_7_3); assign q[8] = ( s_6_0 | !c_7_0 ); assign q8_inv=!q[8]; assign r[8:5]={s_7_3, s_7_2, s_7_1, s_7_0}; assign a[12:1]={a_in[0], a_in[1], a_in[2], a_in[3], a_in[4], a_in[5], a_in[6], a_in[7], 4'b0000}; assign d[4:1]={d_in[0], d_in[1], d_in[2], d_in[3]}; assign q_out[7:0]={q[1] ,q[2], q[3], q[4], q[5], q[6], q[7], q[8]}; assign r_out[3:0]={r[5], r[6], r[7], r[8]}; endmodule //fast_array_divider Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_sda 0 18 сентября, 2015 Опубликовано 18 сентября, 2015 · Жалоба Ну что,продолжим? Параметризуемый полифазный фильтр КИХ. Количество фаз - 2. Реализация - вторая прямая форма,порядок чётный,ИХ симметричная. FilterPoly_2x.rar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 29 января, 2016 Опубликовано 29 января, 2016 · Жалоба Решил поделиться алгоритмом: Например, вам надо понять, является ли введенное число степенью двойки или нет. Для этого вы можете просто делить это число на 2, пока не получите двойку на последнем шаге. Этот алгоритм будет работать, он выдаст результат, но на больших числах будет тратить много лишнего времени. А можете написать простое выражение в одну строку: x & (x-1) == 0. Тут используется немного битовой магии, но результат будет тем же, но за гораздо меньшее время. PS Надеюсь будет кому-то полезным... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 15 29 января, 2016 Опубликовано 29 января, 2016 · Жалоба А можете написать простое выражение в одну строку: x & (x-1) == 0. Тут используется немного битовой магии, но результат будет тем же, но за гораздо меньшее время.Вы не читали "Трюки для программистов"? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 2 марта, 2016 Опубликовано 2 марта, 2016 · Жалоба Решил поделиться алгоритмом: Например, вам надо понять, является ли введенное число степенью двойки или нет. Для этого вы можете просто делить это число на 2, пока не получите двойку на последнем шаге. Этот алгоритм будет работать, он выдаст результат, но на больших числах будет тратить много лишнего времени. А можете написать простое выражение в одну строку: x & (x-1) == 0. Тут используется немного битовой магии, но результат будет тем же, но за гораздо меньшее время. Здесь надо не делить на 2, а подсчитать количество единичных битов, и сравнить его с единицей. Поскольку конкретное значение количества единичных битов вычислять не требуется, стандартная архитектура решения этой задачи упрощается. Например, для 15 бит на Ксайлинксах потребуется три пары LUT5 на нижнем слое логики, и один LUT6 на следующем, как раз один слайс. Нижний слой выдаёт по трём группам из пяти бит значения "нет единиц", "одна единица", "больше одной единицы", а верхний LUT6 выносит окончательный вердикт. А через вычитание потребуются 4 слайса только для вычитания и потом ещё 2 на логику. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 2 марта, 2016 Опубликовано 2 марта, 2016 · Жалоба Если число делится на 2, у него только одна единица среди битов. 4-входовая LUT выдает 1 для чисел 0001, 0010, 0100, 1000. Следующая такая же LUT принимает 4 выхода с предыдущего слоя, и т.д. Красота. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться