-
Постов
3 864 -
Зарегистрирован
Весь контент Maverick_
-
АЦП на базе логики FPGA
Maverick_ опубликовал тема в Работаем с ПЛИС, области применения, выбор
что скажите насчет такой корки - АЦП на базе логики FPGA: https://github.com/LukiLeu/FPGA_ADC - реализация https://dl.acm.org/doi/10.1145/3431920.3439287 - описание работы с видео, рассказывающем как работает и архитектуру "развод" или правда? + https://habr.com/ru/articles/352276/ -
ответ же на 🙂
-
вот взято с темплате vivado2019.1 для verilog // Asynchronous Input Synchronization // // The following code is an example of synchronizing an asynchronous input // of a design to reduce the probability of metastability affecting a circuit. // // The following synthesis and implementation attributes is added to the code // in order improve the MTBF characteristics of the implementation: // // ASYNC_REG="TRUE" - Specifies registers will be receiving asynchronous data // input to allow tools to report and improve metastability // // The following parameters are available for customization: // // SYNC_STAGES - Integer value for number of synchronizing registers, must be 2 or higher // PIPELINE_STAGES - Integer value for number of registers on the output of the // synchronizer for the purpose of improveing performance. // Particularly useful for high-fanout nets. // INIT - Initial value of synchronizer registers upon startup, 1'b0 or 1'b1. parameter SYNC_STAGES = 3; parameter PIPELINE_STAGES = 1; parameter INIT = 1'b0; wire <sync_out>; (* ASYNC_REG="TRUE" *) reg [SYNC_STAGES-1:0] sreg = {SYNC_STAGES{INIT}}; always @(posedge clk) sreg <= {sreg[SYNC_STAGES-2:0], async_in}; generate if (PIPELINE_STAGES==0) begin: no_pipeline assign sync_out = sreg[SYNC_STAGES-1]; end else if (PIPELINE_STAGES==1) begin: one_pipeline reg sreg_pipe = INIT; always @(posedge clk) sreg_pipe <= sreg[SYNC_STAGES-1]; assign sync_out = sreg_pipe; end else begin: multiple_pipeline (* shreg_extract = "no" *) reg [PIPELINE_STAGES-1:0] sreg_pipe = {PIPELINE_STAGES{INIT}}; always @(posedge clk) sreg_pipe <= {sreg_pipe[PIPELINE_STAGES-2:0], sreg[SYNC_STAGES-1]}; assign sync_out = sreg_pipe[PIPELINE_STAGES-1]; end endgenerate для vhdl -- Asynchronous Input Synchronization -- -- The following code is an example of synchronizing an asynchronous input -- of a design to reduce the probability of metastability affecting a circuit. -- -- The following synthesis and implementation attributes are added to the code -- in order improve the MTBF characteristics of the implementation: -- -- ASYNC_REG="TRUE" - Specifies registers will be receiving asynchronous data -- input to allow tools to report and improve metastability -- -- The following constants are available for customization: -- -- SYNC_STAGES - Integer value for number of synchronizing registers, must be 2 or higher -- PIPELINE_STAGES - Integer value for number of registers on the output of the -- synchronizer for the purpose of improveing performance. -- Particularly useful for high-fanout nets. -- INIT - Initial value of synchronizer registers upon startup, 1'b0 or 1'b1. -- Insert the following before begin keyword of architecture constant SYNC_STAGES : integer := 3; constant PIPELINE_STAGES : integer := 1; constant INIT : std_logic := '0'; signal <sync_out> : std_logic; -- Synchronized output signal sreg : std_logic_vector(SYNC_STAGES-1 downto 0) := (others => INIT); attribute async_reg : string; attribute async_reg of sreg : signal is "true"; signal sreg_pipe : std_logic_vector(PIPELINE_STAGES-1 downto 0) := (others => INIT); attribute shreg_extract : string; attribute shreg_extract of sreg_pipe : signal is "false"; -- Insert the following in the architecture after the begin keyword process(<clk>) begin if(<clk>'event and <clk>='1')then sreg <= sreg(SYNC_STAGES-2 downto 0) & <async_in>; -- Async Input <async_in> end if; end process; no_pipeline : if PIPELINE_STAGES = 0 generate begin <sync_out> <= sreg(SYNC_STAGES-1); end generate; one_pipeline : if PIPELINE_STAGES = 1 generate begin process(<clk>) begin if(<clk>'event and <clk>='1') then <sync_out> <= sreg(SYNC_STAGES-1); end if; end process; end generate; multiple_pipeline : if PIPELINE_STAGES > 1 generate begin process(<clk>) begin if(<clk>'event and <clk>='1') then sreg_pipe <= sreg_pipe(PIPELINE_STAGES-2 downto 0) & sreg(SYNC_STAGES-1); end if; end process; <sync_out> <= sreg_pipe(PIPELINE_STAGES-1); end generate;
-
Мое мнение с камеры кадры постоянно отправлять на комп, если команда с ПК пришла то примениться она уже на следующем кадре или через несколько кадров Cкорость принятия данных с камеры: 320*320*3*8*300 =7.4*10^8 bit 2* 7.4*10^8 = 1.5*10^9 bit/s По логике скорость 1,5Гбита/с - комп должен успевать принимать данные с камер, если драйвер + программа будет хорошо работать и операционка правильно настроена. То можно кадры отправлять сразу на ПК, но если ПК подвиснет будет потеря данных. Рассмотрите вариант работы через SDRAM память, чтобы исключить потерю кадров (возможную) - не знаю насколько критично Вам потеря кадра/части кадра, и чтобы иметь возможность отправлять на комп целыми кадрами Как альтернатива - логика ждет начало нового кадра и его отправляет - после возникновения сбоя передачи скорость работы SDRAM какая? У Вас SDRAM или DDR3/4? если DDR3/4 тогда можно организововать двойную буфферизацию - думаю скорости памяти должно хватить - желательно посчитать, попробовать вначале (например передавать значения счетчика - будут видны пропуски данных)
-
работаем по заполнению и освобождению фифо на FT602 если скорость поступления image from camera > скорости USB 3.0 (FT602) тогда через буферизацию кадра изображения внешней памяти (SDRAM, DDR, SRAM)
-
огромное спасибо! и(vivado 2019.1) для module adder_tree # ( parameter int NUM_INPUTS = 16, parameter int DATA_WIDTH = 16, parameter int OUT_DATA_WIDTH = DATA_WIDTH + $clog2(NUM_INPUTS) ) ( input logic clk, input logic clkena, input logic [DATA_WIDTH-1:0] idata [0:NUM_INPUTS-1], output logic [OUT_DATA_WIDTH-1:0] odata ); localparam int NUM_INPUTS_TRUE = 2 ** ($clog2(NUM_INPUTS)); localparam int LP_STAGES = $clog2(NUM_INPUTS); logic [DATA_WIDTH-1:0] in_true [0:NUM_INPUTS_TRUE-1]; logic [OUT_DATA_WIDTH-1:0] adder_out [0:LP_STAGES-1][0:NUM_INPUTS_TRUE/2-1]; //Make zero assignment for unused inputs (in case when NUM_INPUTS ~= power of 2 : genvar inp; generate for (inp=0; inp < NUM_INPUTS_TRUE; inp = inp + 1) begin: inp_assign if(inp < NUM_INPUTS) assign in_true[inp] = idata[inp]; else assign in_true[inp] = '0; end endgenerate genvar stage,adder_num; generate for (stage=0; stage < LP_STAGES; stage = stage + 1) begin: stage_gen localparam int STAGE_IN_W = NUM_INPUTS_TRUE >> stage; localparam int STAGE_OUT_W = STAGE_IN_W/2; localparam int DW_IN = DATA_WIDTH + stage; localparam int DW_OUT = DW_IN + 1; for (adder_num=0; adder_num < STAGE_OUT_W; adder_num = adder_num + 1) begin: adder_gen if(stage == 0) always_ff@(posedge clk) begin if (clkena) begin adder_out[stage][adder_num][DW_OUT-1:0] <= in_true[adder_num*2] + in_true[adder_num*2 + 1]; end end else begin always_ff@(posedge clk) begin if (clkena) begin adder_out[stage][adder_num][DW_OUT-1:0] <= adder_out[stage-1][adder_num*2][DW_IN-1:0] + adder_out[stage-1][adder_num*2 + 1][DW_IN-1:0]; end end end end end endgenerate assign odata = adder_out[LP_STAGES-1][0]; endmodule и в ртл просматровщике
-
помоги пожалуйста добавить в описание сигнал разрешения работи модуля https://electronix.ru/forum/applications/core/interface/file/attachment.php?id=77681 описание от Bad0512
-
помощь с описанием (vhdl)
Maverick_ опубликовал тема в Языки проектирования на ПЛИС (FPGA)
Добра есть данные с NCO (reg_cos, reg_sin) и приходяцие данные (reg_data_re, reg_data_im) далее я описываю фільтр -- //\\\\\\\\\// -- // Mixer I // -- //\\\\\\\\\// process (all) begin if (i_rst = '1') then reg_bpsk_im <= (others => '0'); elsif(rising_edge(i_clk)) then if valid = '1' then reg_bpsk_im <= std_logic_vector(signed(reg_sin) * signed(reg_data_im)); end if; end if; end process; -- //\\\\\\\\\// -- // Mixer Q // -- //\\\\\\\\\// process (all) begin if (i_rst = '1') then reg_bpsk_re <= (others => '0'); elsif(rising_edge(i_clk)) then if valid = '1' then reg_bpsk_re <= std_logic_vector(signed(reg_cos) * signed(reg_data_re)); end if; end if; end process; process (all) begin if (i_rst = '1') then reg_valid <= '0'; valid_out <= '0'; elsif(rising_edge(i_clk)) then reg_valid <= valid; valid_out <= reg_valid; end if; end process; process (all) begin if (i_rst = '1') then mix_im <= (others=>(others=>'0')); elsif(rising_edge(i_clk)) then --mix_im(mix_im'low) <= signed(reg_bpsk_im); --mix_im <= mix_im(mix_im'high); mix_im(0) <= signed(reg_bpsk_im); mix_im(1) <= mix_im(0); mix_im(2) <= mix_im(1); mix_im(3) <= mix_im(2); mix_im(4) <= mix_im(3); mix_im(5) <= mix_im(4); mix_im(6) <= mix_im(5); mix_im(7) <= mix_im(6); mix_im(8) <= mix_im(7); mix_im(9) <= mix_im(8); end if; end process; process (all) begin if (i_rst = '1') then mix_re <= (others=>(others=>'0')); elsif(rising_edge(i_clk)) then --mix_re(mix_re'low) <= signed(reg_bpsk_re); --mix_re <= mix_re(mix_re'high); mix_re(0) <= signed(reg_bpsk_re); mix_re(1) <= mix_re(0); mix_re(2) <= mix_re(1); mix_re(3) <= mix_re(2); mix_re(4) <= mix_re(3); mix_re(5) <= mix_re(4); mix_re(6) <= mix_re(5); mix_re(7) <= mix_re(6); mix_re(8) <= mix_re(7); mix_re(9) <= mix_re(8); end if; end process; -- //\\\\\\\\\\\\\\\\\\\// -- // Low-pass Filter I // -- //\\\\\\\\\\\\\\\\\\\// process (all) begin if (i_rst = '1') then LpfI <= (others=>'0'); elsif(rising_edge(i_clk)) then LpfI <= mix_im(0) + mix_im(1) + mix_im(2) + mix_im(3) + mix_im(4) + mix_im(5) + mix_im(6) + mix_im(7) + mix_im(8) + mix_im(9); end if; end process; process (all) begin if (i_rst = '1') then LpfQ <= (others=>'0'); elsif(rising_edge(i_clk)) then LpfQ <= mix_re(0) + mix_re(1) + mix_re(2) + mix_re(3) + mix_re(4) + mix_re(5) + mix_re(6) + mix_re(7) + mix_re(8) + mix_re(9); end if; end process; мне такое описание не нравиться из-за строк вычисляющих LpfI и LpfQ подскажите как можно/нужно по другому описать PS внутренний голос говорит что описание - FIR filter -
Помощь с core atan
Maverick_ ответил Maverick_ тема в Языки проектирования на ПЛИС (FPGA)
большое спасибо des00 -
Помощь с core atan
Maverick_ ответил Maverick_ тема в Языки проектирования на ПЛИС (FPGA)
я прочитал readme.txt не сколько раз, но смотрю симуляцию вижу X, Y и результат беру числа с симуляции подставляю в матлаб (использую функцию atan2(Y,X)) - не совпадает не могу понять что я делаю не так Скриншот симуляции: например в матлабе atan2(-120,-128) ans = -2.3884 -
Помощь с core atan
Maverick_ ответил Maverick_ тема в Языки проектирования на ПЛИС (FPGA)
des00 подскажите пожалуйста входные данные в Вашем описании как я понимаю положительные, т.е. находятся в 1 квадранте пытаюсь сравнить результаты с matlab но у меня не сходиться (в матлабе использую функцию atan2(Y,X)) прошу помощи разобраться PS работы много, а желание разобраться осталось cordic_script_des00.zip -
tcl скрипт добавляющий модули на waveform, если с сохранением иерархии проекта вообще супер
-
логи на форум - только прикрепленным txt файлом!!! Модератор PS как я прикрепил Ваш лог файл... log.txt
-
сейчас да вот как раз и думаю как лучще как дальше работать? возможно на modelsim придется перейти...
-
generic vhdl module to waveform
Maverick_ опубликовал тема в Работаем с ПЛИС, области применения, выбор
Добра Работаю в vivado 2019.1 Есть проект в котором через generic (vhdl) - сделано несколько копий одного модуля. Сейчас потребовалось вывести на waveform чтобы проверить работу. Проблема в том что модуль имеет много вложенных компонентов/модулей и "врукопашную" выводить каждый модуль на waveform долго и велика вероятность ошибки... Можно ли єто автоматизировать? Может кто-то поделиться готовым tcl скриптом? ))) -
Инициализация вектора
Maverick_ ответил jenya7 тема в Языки проектирования на ПЛИС (FPGA)
так, для каждого елемента прописиваешь значение type rom_array is array(0 to 2**ADDR-1) of std_logic_vector(DATA-1 downto 0); constant mem : rom_array := ( x"0A732DF5", x"0A72DA12", x"0A72862F", x"0A72324D", x"0A71DE6A", x"0A718A87", x"0A7136A4", x"0A70E2C1", x"0A708EDE", x"0A703AFB", x"0A6FE719", x"0A6F9336", x"0A6F3F53", x"0A6EEB70", x"0A6E978D", x"0A6E43AA", x"0A6DEFC8", x"0A6D9BE5", x"0A6D4802", x"0A6CF41F", x"0A6CA03C", x"0A7381D8", x"0A732DF5", x"0A72DA12", x"0A72862F", x"0A72324D", x"0A71DE6A", x"0A718A87", x"0A7136A4", x"0A70E2C1", x"0A708EDE", x"0A703AFB", x"0A6FE719", x"0A6F9336", x"0A6F3F53", x"0A6EEB70", x"0A6E978D", x"0A6E43AA", x"0A6DEFC8", x"0A6D9BE5", x"0A6D4802", x"0A6CF41F", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000" ); можно через функцию library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use IEEE.NUMERIC_STD.ALL; entity bram_tdp is generic ( DATA : integer := 32; ADDR : integer := 12 ); port ( -- Port A a_clk : in std_logic; --ena : in std_logic; a_wr : in std_logic; a_addr : in std_logic_vector(ADDR-1 downto 0); a_din : in std_logic_vector(DATA-1 downto 0); a_dout : out std_logic_vector(DATA-1 downto 0); -- Port B b_clk : in std_logic; --enb : in std_logic; b_wr : in std_logic; b_addr : in std_logic_vector(ADDR-1 downto 0); b_din : in std_logic_vector(DATA-1 downto 0); b_dout : out std_logic_vector(DATA-1 downto 0) ); end bram_tdp; architecture rtl of bram_tdp is -- Shared memory type mem_type is array ( (2**ADDR)-1 downto 0 ) of std_logic_vector(DATA-1 downto 0); -- FUNCTION initialize_ram return mem_type is variable result : mem_type; -- variable v_TEMP : std_logic_vector(((DATA/2)-1) downto 0); -- BEGIN -- v_TEMP := (others => '1'); -- FOR i IN ((2**ADDR)-1) DOWNTO 0 LOOP -- result(i) := v_TEMP & std_logic_vector( to_unsigned(natural(i), natural'((DATA/2)))); -- END LOOP; -- RETURN result; -- END initialize_ram; FUNCTION initialize_ram return mem_type is variable result : mem_type; BEGIN FOR i IN ((2**ADDR)-1) DOWNTO 0 LOOP result(i) := std_logic_vector( to_unsigned(natural(i), natural'((DATA)))); END LOOP; RETURN result; END initialize_ram; shared variable mem : mem_type := initialize_ram; -- shared variable mem : mem_type := (others => (others => '0')); -- := initialize_ram; begin -- Port A process(a_clk) begin if(a_clk'event and a_clk='1') then -- if ena = '1' then if(a_wr='1') then mem(conv_integer(a_addr)) := a_din; end if; a_dout <= mem(conv_integer(a_addr)); -- end if; end if; end process; -- Port B process(b_clk) begin if(b_clk'event and b_clk='1') then --- if enb = '1' then if(b_wr='1') then mem(conv_integer(b_addr)) := b_din; end if; b_dout <= mem(conv_integer(b_addr)); -- end if; end if; end process; end rtl; можно проинициализировать массив нулями потом дополнительно проинициализировать необходимые єлементы отдельно type t_Five is array (0 to 4) of bit_vector(15 downto 0); signal r_Calc : t_Five := (others => (others => '0')); r_Calc (1) <= std_logic_vector(to_unsigned(15, r_Calc'length); -
LVDS на CycloneV
Maverick_ ответил sirop тема в Работаем с ПЛИС, области применения, выбор
Задано ж 600Mbit/s output data rate (2 картинкa) 600 Mbps/8 deserialization factory = 75 МГц будет время почитайте + link -
посмотрите - может поможет + проверьте на задание i - конечное значение не должно быть больше числа єлементов в массиве - даже изначально заданное если там счетчик задающий - i - ограничьте счет до количества єлементов в массиве как в примере ниже library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity counter is generic ( DATA_WIDTH : integer := 24; MAX_VALUE : integer := 128 -- maximum count value ); port ( clk : in std_logic; -- input clock signal rst : in std_logic; -- asynchronous reset input signal count : out std_logic_vector(DATA_WIDTH-1 downto 0) -- 7-bit count output signal ); end entity counter; architecture rtl of counter is signal reg_count : std_logic_vector(DATA_WIDTH-1 downto 0); -- register to hold the count value begin -- increment the count value on each rising edge of the clock process (all) begin if rst = '1' then reg_count <= (others => '0'); -- reset the count value elsif rising_edge(clk) then if reg_count = std_logic_vector(to_unsigned(MAX_VALUE - 1, reg_count'length)) then reg_count <= (others => '0'); -- reset the count value if it reaches MAX_VALUE else reg_count <= std_logic_vector(unsigned(reg_count) + 1); -- increment the count value end if; end if; end process; -- output the count value count <= reg_count; end rtl; и чило i должно быть unsigned или задающее его - mac_result_scaled
-
мое описание не пробовали симулировать?
-
https://github.com/gaab0r/median_filter/blob/master/median_filter.srcs/sources_1/new/sorter.vhd лучше опишите pipeline схему https://www.ijedr.org/papers/IJEDRCP1401003.pdf Figure 2: Proposed systolic array of optimized approach будет єфективнее может потом поделитесь))) в дополнение https://www.ripublication.com/ijaer17/ijaerv12n24_289.pdf можно немного иначе реализовать https://www.researchgate.net/publication/317662545_An_FPGA_Implementation_of_a_Fast_2-Dimensional_Median_Filter Figure 3: The Hardware architecture of Median Filter можно так попробоапть library ieee; use ieee.std_logic_1164.all; library work; package Const_type is type my_array is array (0 to 16) of std_logic_vector (11 downto 0) ; end package; library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use work.Const_type.all; entity proverka is Port ( CLK : in std_logic; din : in std_logic_vector (11 downto 0) ; dout : out my_array ); end proverka; architecture behavioral of proverka is begin process (clk) variable z : std_logic_vector (11 downto 0) ; variable x : my_array := (others => "000000000000"); begin if (CLK'event and CLK ='1') then for i in 1 to 16 loop if ( din > x(i) ) then z := din; x(i-1) := x(i); x(i) := z; end if; end loop; dout <= x; end if; end process; end behavioral;
-
Для чего Вам сортировка понадобилась? У Вас же данние приходят последовательно - почему не хотите использовать сортировку которую я Вам дал?
-
QDRIV Artix-7
Maverick_ ответил DadaLife тема в Языки проектирования на ПЛИС (FPGA)
http://www.bdtic.com/download/XILINX/xapp886.pdf https://www.infineon.com/dgdl/Infineon-AN84060_QDR_-IV_Design_Guide-ApplicationNotes-v07_00-EN.pdf?fileId=8ac78c8c7cdc391c017d0724052b4806 -
Вы должны сделать промежуточную логику приема и отправки даных по интерфесу(QuadSPI) и интерфейса flash памяти в max10. Да скорее всего потребуется сделать парсер команд и формирователь пакетов-ответов для процессора. jenya7 я случайно ответил в Вашем сообщении - прошу прощения...
-
можно процессор внешний к fpga? интерфейс какой доступен у него для организации dma? можно если например у процессора SPI то на логике FPGA делаете приемник команд и ответ на команди по SPI - логика на FPGA общается c FLASH PS link + логика внешнего интерфейса (SPI, QuadSPI, I2C, SRAM и так далее) на FPGA для связи с внешним процессором PS возможно придется на логике повторить комади IS25WP128 - зависит от процессора
-
des00 имел ввиду скорее всего что будет Ваша корка SDRAM соедениться с моделью микросхемы. Начнете симуляцию .... Но для начала Вам надо скомпилировать библиотеку корок для симулятора - делается в среде разработки... Потом пути прописать.... например в вивадо