Перейти к содержанию
    

Maverick_

Модератор
  • Постов

    3 864
  • Зарегистрирован

Весь контент Maverick_


  1. "do0, do1, do2, do3 это отсортированные значения ?" Да Я ниже привел тестбенч попробуйте запустить симуляцию и все станет ясно как работет. Или посмотрите тестбенч - как я подаю сигналы на вход
  2. ------------------------------------------------------------------------------ -- Описание приведено для поиска четырех минимальных чисел. -- Легко масштабируется путем увеличения количества модулей sort_list_cell. -- Значение на входе сохраняется в модуле sort_list_cell, -- начиная с которого это значение превосходит значение -- регистра dout (условие позиции вставки: cprev = 0 и cout = 1). -- Остальные модули, у которых din < dout, берут новое значение -- регистра dout с выхода предыдущего модуля. -- dprev - содержимое регистра предыдущего модуля -- cprev - значение на входе din больше чем dprev -- cout - значение на входе din больше чем dout -- do0 - максимальное значение -- do3 - минимальное значение ------------------------------------------------------------------------------ library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity sort_list is port(clk, en, rst : in std_logic; din : in std_logic_vector(3 downto 0); insert_out : out std_logic; do0, do1, do2, do3 : out std_logic_vector(3 downto 0)); end sort_list; architecture archi of sort_list is component sort_list_cell is port(clk, en, rst : in std_logic; din : in std_logic_vector(3 downto 0); dprev : in std_logic_vector(3 downto 0); cprev : in std_logic; cout : out std_logic; dout : out std_logic_vector(3 downto 0)); end component sort_list_cell; signal reg_cout0, reg_cout1, reg_cout2, reg_cout3: std_logic; signal reg_do0, reg_do1, reg_do2, reg_do3 : std_logic_vector(3 downto 0); signal reg_insert : std_logic; begin cell_3 : sort_list_cell port map ( clk => clk, en => en, rst => rst, din => din, dprev => reg_do2, cprev => reg_cout2, dout => reg_do3, cout => reg_cout3); cell_2 : sort_list_cell port map ( clk => clk, en => en, rst => rst, din => din, dprev => reg_do1, cprev => reg_cout1, dout => reg_do2, cout => reg_cout2); cell_1 : sort_list_cell port map ( clk => clk, en => en, rst => rst, din => din, dprev => reg_do0, cprev => reg_cout0, dout => reg_do1, cout => reg_cout1); cell_0 : sort_list_cell port map ( clk => clk, en => en, rst => rst, din => din, dprev => (others => '0'), cprev => '0', dout => reg_do0, cout => reg_cout0); do0 <= reg_do0; do1 <= reg_do1; do2 <= reg_do2; do3 <= reg_do3; reg_insert <= ('0' and reg_cout0) or (reg_cout0 and reg_cout1) or (reg_cout1 and reg_cout2) or (reg_cout2 and reg_cout3); insert_out <= reg_insert; end archi; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity sort_list_cell is port(clk, en, rst : in std_logic; din : in std_logic_vector(3 downto 0); dprev : in std_logic_vector(3 downto 0); cprev : in std_logic; cout : out std_logic; dout : out std_logic_vector(3 downto 0)); end sort_list_cell; architecture archi of sort_list_cell is signal reg_dout: std_logic_vector(3 downto 0); signal reg_cout: std_logic; begin reg_cout <= '1' WHEN din < reg_dout ELSE '0'; cout <= reg_cout; process (clk, en, rst) begin if rst = '1' then reg_dout <= (others => '1'); elsif (clk'event and clk='1') then if(en and reg_cout) = '1' then if cprev = '1' then reg_dout <= dprev; else reg_dout <= din; end if; end if; end if; end process; dout <= reg_dout; end archi; я думаю данные для сортировки у вас появляються последовательно, тогда данный вариант должен подойти
  3. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity Pipeline_Counter is generic ( width_g: natural := 64; -- Must be divisible by parts_g. parts_g: natural := 4 ); port ( clk: in std_logic; rst_n: in std_logic; clear: in std_logic; enable: in std_logic; count: out std_logic_vector(width_g - 1 downto 0); tick: out std_logic ); end Pipeline_Counter; architecture rtl of Pipeline_Counter is constant part_width_c: natural := width_g / parts_g; signal almost_tick_r: std_logic_vector(parts_g - 1 downto 0); signal count_r: std_logic_vector(width_g - 1 downto 0); begin count <= count_r; process (clk, rst_n) variable part_v: unsigned(part_width_c - 1 downto 0); variable tick_v: std_logic; begin if rst_n = '0' then count_r <= (others => '0'); almost_tick_r <= (others => '0'); tick <= '0'; elsif rising_edge(clk) then tick_v := enable; for i in 0 to parts_g - 1 loop part_v := unsigned(count_r((i + 1) * part_width_c - 1 downto i * part_width_c)); if tick_v = '1' then -- Value is max - 1? if part_v = to_unsigned(2**part_width_c - 2, part_width_c) then almost_tick_r(i) <= '1'; else almost_tick_r(i) <= '0'; end if; part_v := part_v + 1; end if; count_r((i + 1) * part_width_c - 1 downto i * part_width_c) <= std_logic_vector(part_v); tick_v := tick_v and almost_tick_r(i); end loop; tick <= tick_v; if clear = '1' then count_r <= (others => '0'); almost_tick_r <= (others => '0'); tick <= '0'; end if; end if; end process; end architecture; testbench library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity tb_pipeline_counter is end entity; architecture testbench of tb_pipeline_counter is signal clk, rst_n: std_logic; signal clear: std_logic; signal enable: std_logic; signal count: std_logic_vector(15 downto 0); signal tick: std_logic; begin cnt1: entity work.Pipeline_Counter generic map (width_g => 16, parts_g => 4) port map (clk, rst_n, clear, enable, count, tick); process procedure clock is constant PERIOD: time := 1 us; begin clk <= '0'; wait for PERIOD/2; clk <= '1'; wait for PERIOD/2; end procedure; begin rst_n <= '0'; clear <= '0'; enable <= '0'; clock; rst_n <= '1'; enable <= '1'; for i in 0 to 65535 loop assert unsigned(count) = to_unsigned(i, 16) report "Wrong count, " & integer'image(to_integer(unsigned(count))) & " expected " & integer'image(i); assert tick = '0' report "Unexpected tick"; clock; end loop; assert count = X"0000" report "Expected to roll over"; assert tick = '1' report "Expected tick"; clock; assert count = X"0001"; clear <= '1'; clock; clear <= '0'; assert count = X"0000" report "Counter should clear"; clock; assert count = X"0001"; report "Simulation ended" severity note; wait; end process; end architecture;
  4. это сигнал разрешения, если приходящие данные и выставлен i_data_ena = 1 то эти данные будут учитываться в вычислениях среднего иначе нет как-то так
  5. возможно это поможет library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity moving_average is generic ( G_NBIT : integer := 8; G_AVG_LEN_LOG : integer := 2 ); port ( i_clk : in std_logic; i_rstb : in std_logic; i_sync_reset : in std_logic; -- input i_data_ena : in std_logic; i_data : in std_logic_vector(G_NBIT-1 downto 0); -- output o_data_valid : out std_logic; o_data : out std_logic_vector(G_NBIT-1 downto 0)); end moving_average; architecture rtl of moving_average is type t_moving_average is array (0 to 2**G_AVG_LEN_LOG-1) of signed(G_NBIT-1 downto 0); signal p_moving_average : t_moving_average; signal r_acc : signed(G_NBIT+G_AVG_LEN_LOG-1 downto 0); -- average accumulator signal r_data_valid : std_logic; begin p_average : process(i_clk,i_rstb) begin if(i_rstb='0') then r_acc <= (others=>'0'); p_moving_average <= (others=>(others=>'0')); r_data_valid <= '0'; o_data_valid <= '0'; o_data <= (others=>'0'); elsif(rising_edge(i_clk)) then r_data_valid <= i_data_ena; o_data_valid <= r_data_valid; if(i_sync_reset='1') then r_acc <= (others=>'0'); p_moving_average <= (others=>(others=>'0')); elsif(i_data_ena='1') then p_moving_average <= signed(i_data)&p_moving_average(0 to p_moving_average'length-2); r_acc <= r_acc + signed(i_data)-p_moving_average(p_moving_average'length-1); end if; o_data <= std_logic_vector(r_acc(G_NBIT+G_AVG_LEN_LOG-1 downto G_AVG_LEN_LOG)); -- divide by 2^G_AVG_LEN_LOG end if; end process p_average; end rtl;
  6. Подумайте может "ножки JTAG завели на HPS-часть ПЛИС." может все таки на FPGA - гибкости больше будет
  7. Выкладывайте. Можете сразу сделать ссылку здесь :)
  8. После проведения множества тестов с измерением средствами Linux, было решено перейти к решению на основе счетчика, реализованного в части логики. Такой подход показывает результаты лучше, чем предыдущий и уже можно ориентироваться на результаты измерений. Но есть проблема с тем, что в избранном API (https://github.com/digibird1/Cyclone-V-SoC-system_Base/blob/master/SoC_Memory_2/sgdma.h) все равно присутствует функция остановки (nanosleep). Если функцию waitFinish() там реализовать просто как while, который ожидает условие, то ничего не передается, т.к. постоянно опрашивается модуль. Если оставить функцию printf(), то все измеряется, но это также идет в счет измеряемого времени. Есть ли какие-либо способы обойти момент с вызовом доп. функций в while'е?
  9. Как пример реализовать генерацию синуса приведено ниже: -- Module Name: sine_table - Behavioral -- Description: A lookup table with interpolation for sin(x) function -- -- To help with the coding, this actually returns sin(x+2*pi/8192) -- subtract 0x70 from 'phase' to keep the zero crossing at zero. ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity sine_table is Port ( clk : in STD_LOGIC; phase : in STD_LOGIC_VECTOR (17 downto 0); sine : out STD_LOGIC_VECTOR (19 downto 0)); end sine_table; architecture Behavioral of sine_table is signal sine_sum : unsigned(9+phase'high downto 0) := (others => '0'); signal sine_mult_1 : unsigned(9+phase'high downto 0) := (others => '0'); signal frac_1 : unsigned(phase'high-11 downto 0) := (others => '0'); signal sine_1 : unsigned(19 downto 0) := (others => '0'); signal index_1 : unsigned(11 downto 0) := (others => '0'); signal quad_1 : unsigned( 1 downto 0) := (others => '0'); signal entry_1 : unsigned( 9 downto 0) := (others => '0'); signal sine_mult_2 : unsigned(9+phase'high downto 0) := (others => '0'); signal frac_2 : unsigned(phase'high-11 downto 0) := (others => '0'); signal sine_2 : unsigned(19 downto 0) := (others => '0'); signal quad_2 : unsigned(1 downto 0) := (others => '0'); signal entry_2 : unsigned(9 downto 0) := (others => '0'); signal index_2 : unsigned(11 downto 0) := (others => '0'); signal frac : unsigned(phase'high-12 downto 0); constant frac_max : unsigned(phase'high-11 downto 0) := (phase'high-11 => '1', others => '0'); constant table_max : unsigned(9 downto 0) := (others => '1'); constant midrange : unsigned(19 downto 0) := x"80000"; type a_mem is array (0 to 1023) of unsigned (19 downto 0); signal mem : a_mem := ( x"000C9", x"0025B", x"003ED", x"0057F", x"00711", x"008A3", x"00A35", x"00BC7", x"00D59", x"00EEC", x"0107E", x"01210", x"013A2", x"01534", x"016C6", x"01858", x"019EA", x"01B7C", x"01D0E", x"01EA0", x"02032", x"021C4", x"02355", x"024E7", x"02679", x"0280B", x"0299D", x"02B2F", x"02CC0", x"02E52", x"02FE4", x"03175", x"03307", x"03499", x"0362A", x"037BC", x"0394D", x"03ADF", x"03C70", x"03E02", x"03F93", x"04124", x"042B6", x"04447", x"045D8", x"04769", x"048FA", x"04A8B", x"04C1C", x"04DAD", x"04F3E", x"050CF", x"05260", x"053F1", x"05582", x"05712", x"058A3", x"05A34", x"05BC4", x"05D55", x"05EE5", x"06075", x"06206", x"06396", x"06526", x"066B6", x"06846", x"069D6", x"06B66", x"06CF6", x"06E86", x"07016", x"071A5", x"07335", x"074C5", x"07654", x"077E3", x"07973", x"07B02", x"07C91", x"07E20", x"07FAF", x"0813E", x"082CD", x"0845C", x"085EB", x"08779", x"08908", x"08A96", x"08C25", x"08DB3", x"08F41", x"090CF", x"0925D", x"093EB", x"09579", x"09707", x"09894", x"09A22", x"09BB0", x"09D3D", x"09ECA", x"0A057", x"0A1E5", x"0A372", x"0A4FF", x"0A68B", x"0A818", x"0A9A5", x"0AB31", x"0ACBE", x"0AE4A", x"0AFD6", x"0B162", x"0B2EE", x"0B47A", x"0B606", x"0B792", x"0B91D", x"0BAA9", x"0BC34", x"0BDBF", x"0BF4A", x"0C0D5", x"0C260", x"0C3EB", x"0C575", x"0C700", x"0C88A", x"0CA15", x"0CB9F", x"0CD29", x"0CEB3", x"0D03C", x"0D1C6", x"0D350", x"0D4D9", x"0D662", x"0D7EC", x"0D975", x"0DAFD", x"0DC86", x"0DE0F", x"0DF97", x"0E120", x"0E2A8", x"0E430", x"0E5B8", x"0E740", x"0E8C7", x"0EA4F", x"0EBD6", x"0ED5D", x"0EEE5", x"0F06C", x"0F1F2", x"0F379", x"0F500", x"0F686", x"0F80C", x"0F992", x"0FB18", x"0FC9E", x"0FE24", x"0FFA9", x"1012E", x"102B3", x"10438", x"105BD", x"10742", x"108C6", x"10A4B", x"10BCF", x"10D53", x"10ED7", x"1105B", x"111DE", x"11362", x"114E5", x"11668", x"117EB", x"1196E", x"11AF0", x"11C73", x"11DF5", x"11F77", x"120F9", x"1227A", x"123FC", x"1257D", x"126FE", x"1287F", x"12A00", x"12B81", x"12D01", x"12E81", x"13002", x"13181", x"13301", x"13481", x"13600", x"1377F", x"138FE", x"13A7D", x"13BFC", x"13D7A", x"13EF8", x"14076", x"141F4", x"14372", x"144EF", x"1466C", x"147E9", x"14966", x"14AE3", x"14C5F", x"14DDC", x"14F58", x"150D3", x"1524F", x"153CB", x"15546", x"156C1", x"1583C", x"159B6", x"15B31", x"15CAB", x"15E25", x"15F9F", x"16118", x"16292", x"1640B", x"16584", x"166FC", x"16875", x"169ED", x"16B65", x"16CDD", x"16E55", x"16FCC", x"17143", x"172BA", x"17431", x"175A7", x"1771E", x"17894", x"17A0A", x"17B7F", x"17CF5", x"17E6A", x"17FDF", x"18153", x"182C8", x"1843C", x"185B0", x"18724", x"18897", x"18A0A", x"18B7E", x"18CF0", x"18E63", x"18FD5", x"19147", x"192B9", x"1942B", x"1959C", x"1970D", x"1987E", x"199EF", x"19B5F", x"19CCF", x"19E3F", x"19FAF", x"1A11E", x"1A28D", x"1A3FC", x"1A56B", x"1A6D9", x"1A847", x"1A9B5", x"1AB23", x"1AC90", x"1ADFD", x"1AF6A", x"1B0D6", x"1B243", x"1B3AF", x"1B51B", x"1B686", x"1B7F1", x"1B95C", x"1BAC7", x"1BC31", x"1BD9C", x"1BF06", x"1C06F", x"1C1D9", x"1C342", x"1C4AA", x"1C613", x"1C77B", x"1C8E3", x"1CA4B", x"1CBB3", x"1CD1A", x"1CE81", x"1CFE7", x"1D14E", x"1D2B4", x"1D419", x"1D57F", x"1D6E4", x"1D849", x"1D9AE", x"1DB12", x"1DC76", x"1DDDA", x"1DF3E", x"1E0A1", x"1E204", x"1E366", x"1E4C9", x"1E62B", x"1E78D", x"1E8EE", x"1EA4F", x"1EBB0", x"1ED11", x"1EE71", x"1EFD1", x"1F131", x"1F290", x"1F3EF", x"1F54E", x"1F6AC", x"1F80B", x"1F968", x"1FAC6", x"1FC23", x"1FD80", x"1FEDD", x"20039", x"20195", x"202F1", x"2044C", x"205A8", x"20702", x"2085D", x"209B7", x"20B11", x"20C6A", x"20DC4", x"20F1D", x"21075", x"211CD", x"21325", x"2147D", x"215D4", x"2172B", x"21882", x"219D8", x"21B2E", x"21C84", x"21DDA", x"21F2F", x"22083", x"221D8", x"2232C", x"2247F", x"225D3", x"22726", x"22879", x"229CB", x"22B1D", x"22C6F", x"22DC0", x"22F11", x"23062", x"231B3", x"23303", x"23452", x"235A2", x"236F1", x"2383F", x"2398E", x"23ADC", x"23C29", x"23D77", x"23EC4", x"24010", x"2415D", x"242A9", x"243F4", x"2453F", x"2468A", x"247D5", x"2491F", x"24A69", x"24BB2", x"24CFB", x"24E44", x"24F8D", x"250D5", x"2521C", x"25364", x"254AB", x"255F1", x"25738", x"2587E", x"259C3", x"25B08", x"25C4D", x"25D92", x"25ED6", x"26019", x"2615D", x"262A0", x"263E2", x"26525", x"26666", x"267A8", x"268E9", x"26A2A", x"26B6A", x"26CAA", x"26DEA", x"26F29", x"27068", x"271A7", x"272E5", x"27423", x"27560", x"2769D", x"277DA", x"27916", x"27A52", x"27B8D", x"27CC8", x"27E03", x"27F3D", x"28077", x"281B1", x"282EA", x"28423", x"2855B", x"28693", x"287CB", x"28902", x"28A39", x"28B6F", x"28CA5", x"28DDB", x"28F10", x"29045", x"2917A", x"292AE", x"293E2", x"29515", x"29648", x"2977A", x"298AC", x"299DE", x"29B0F", x"29C40", x"29D71", x"29EA1", x"29FD0", x"2A100", x"2A22F", x"2A35D", x"2A48B", x"2A5B9", x"2A6E6", x"2A813", x"2A93F", x"2AA6B", x"2AB97", x"2ACC2", x"2ADED", x"2AF17", x"2B041", x"2B16B", x"2B294", x"2B3BD", x"2B4E5", x"2B60D", x"2B734", x"2B85B", x"2B982", x"2BAA8", x"2BBCE", x"2BCF3", x"2BE18", x"2BF3D", x"2C061", x"2C184", x"2C2A8", x"2C3CA", x"2C4ED", x"2C60F", x"2C730", x"2C851", x"2C972", x"2CA92", x"2CBB2", x"2CCD2", x"2CDF0", x"2CF0F", x"2D02D", x"2D14B", x"2D268", x"2D385", x"2D4A1", x"2D5BD", x"2D6D8", x"2D7F3", x"2D90E", x"2DA28", x"2DB42", x"2DC5B", x"2DD74", x"2DE8C", x"2DFA4", x"2E0BC", x"2E1D3", x"2E2EA", x"2E400", x"2E515", x"2E62B", x"2E740", x"2E854", x"2E968", x"2EA7B", x"2EB8E", x"2ECA1", x"2EDB3", x"2EEC5", x"2EFD6", x"2F0E7", x"2F1F7", x"2F307", x"2F416", x"2F525", x"2F634", x"2F742", x"2F850", x"2F95D", x"2FA69", x"2FB76", x"2FC81", x"2FD8D", x"2FE97", x"2FFA2", x"300AC", x"301B5", x"302BE", x"303C7", x"304CF", x"305D6", x"306DD", x"307E4", x"308EA", x"309F0", x"30AF5", x"30BFA", x"30CFE", x"30E02", x"30F06", x"31009", x"3110B", x"3120D", x"3130E", x"3140F", x"31510", x"31610", x"31710", x"3180F", x"3190D", x"31A0B", x"31B09", x"31C06", x"31D03", x"31DFF", x"31EFB", x"31FF6", x"320F1", x"321EB", x"322E5", x"323DF", x"324D7", x"325D0", x"326C8", x"327BF", x"328B6", x"329AC", x"32AA2", x"32B98", x"32C8D", x"32D81", x"32E75", x"32F69", x"3305C", x"3314E", x"33240", x"33332", x"33423", x"33513", x"33603", x"336F3", x"337E2", x"338D0", x"339BF", x"33AAC", x"33B99", x"33C86", x"33D72", x"33E5D", x"33F48", x"34033", x"3411D", x"34207", x"342F0", x"343D8", x"344C0", x"345A8", x"3468F", x"34775", x"3485B", x"34941", x"34A26", x"34B0A", x"34BEE", x"34CD2", x"34DB5", x"34E97", x"34F79", x"3505B", x"3513C", x"3521C", x"352FC", x"353DC", x"354BA", x"35599", x"35677", x"35754", x"35831", x"3590D", x"359E9", x"35AC4", x"35B9F", x"35C79", x"35D53", x"35E2C", x"35F05", x"35FDD", x"360B5", x"3618C", x"36262", x"36339", x"3640E", x"364E3", x"365B8", x"3668C", x"3675F", x"36832", x"36905", x"369D6", x"36AA8", x"36B79", x"36C49", x"36D19", x"36DE8", x"36EB7", x"36F85", x"37053", x"37120", x"371EC", x"372B8", x"37384", x"3744F", x"3751A", x"375E4", x"376AD", x"37776", x"3783E", x"37906", x"379CD", x"37A94", x"37B5A", x"37C20", x"37CE5", x"37DAA", x"37E6E", x"37F31", x"37FF4", x"380B7", x"38178", x"3823A", x"382FB", x"383BB", x"3847B", x"3853A", x"385F8", x"386B7", x"38774", x"38831", x"388EE", x"389AA", x"38A65", x"38B20", x"38BDA", x"38C94", x"38D4D", x"38E06", x"38EBE", x"38F75", x"3902C", x"390E3", x"39199", x"3924E", x"39303", x"393B7", x"3946B", x"3951E", x"395D0", x"39683", x"39734", x"397E5", x"39895", x"39945", x"399F4", x"39AA3", x"39B51", x"39BFF", x"39CAC", x"39D58", x"39E04", x"39EB0", x"39F5B", x"3A005", x"3A0AE", x"3A158", x"3A200", x"3A2A8", x"3A350", x"3A3F7", x"3A49D", x"3A543", x"3A5E8", x"3A68C", x"3A731", x"3A7D4", x"3A877", x"3A919", x"3A9BB", x"3AA5D", x"3AAFD", x"3AB9D", x"3AC3D", x"3ACDC", x"3AD7A", x"3AE18", x"3AEB6", x"3AF52", x"3AFEE", x"3B08A", x"3B125", x"3B1C0", x"3B259", x"3B2F3", x"3B38B", x"3B424", x"3B4BB", x"3B552", x"3B5E9", x"3B67F", x"3B714", x"3B7A9", x"3B83D", x"3B8D0", x"3B963", x"3B9F6", x"3BA88", x"3BB19", x"3BBAA", x"3BC3A", x"3BCCA", x"3BD59", x"3BDE7", x"3BE75", x"3BF02", x"3BF8F", x"3C01B", x"3C0A6", x"3C131", x"3C1BC", x"3C245", x"3C2CF", x"3C357", x"3C3DF", x"3C467", x"3C4EE", x"3C574", x"3C5FA", x"3C67F", x"3C703", x"3C787", x"3C80B", x"3C88E", x"3C910", x"3C992", x"3CA13", x"3CA93", x"3CB13", x"3CB92", x"3CC11", x"3CC8F", x"3CD0D", x"3CD8A", x"3CE06", x"3CE82", x"3CEFD", x"3CF78", x"3CFF2", x"3D06B", x"3D0E4", x"3D15C", x"3D1D4", x"3D24B", x"3D2C2", x"3D337", x"3D3AD", x"3D421", x"3D496", x"3D509", x"3D57C", x"3D5EE", x"3D660", x"3D6D1", x"3D742", x"3D7B2", x"3D821", x"3D890", x"3D8FE", x"3D96C", x"3D9D9", x"3DA46", x"3DAB1", x"3DB1D", x"3DB87", x"3DBF1", x"3DC5B", x"3DCC4", x"3DD2C", x"3DD94", x"3DDFB", x"3DE61", x"3DEC7", x"3DF2C", x"3DF91", x"3DFF5", x"3E059", x"3E0BC", x"3E11E", x"3E180", x"3E1E1", x"3E241", x"3E2A1", x"3E301", x"3E35F", x"3E3BD", x"3E41B", x"3E478", x"3E4D4", x"3E530", x"3E58B", x"3E5E5", x"3E63F", x"3E699", x"3E6F1", x"3E749", x"3E7A1", x"3E7F8", x"3E84E", x"3E8A4", x"3E8F9", x"3E94D", x"3E9A1", x"3E9F5", x"3EA47", x"3EA99", x"3EAEB", x"3EB3C", x"3EB8C", x"3EBDC", x"3EC2B", x"3EC79", x"3ECC7", x"3ED14", x"3ED61", x"3EDAD", x"3EDF8", x"3EE43", x"3EE8D", x"3EED7", x"3EF20", x"3EF68", x"3EFB0", x"3EFF7", x"3F03E", x"3F084", x"3F0C9", x"3F10E", x"3F152", x"3F196", x"3F1D9", x"3F21B", x"3F25D", x"3F29E", x"3F2DE", x"3F31E", x"3F35D", x"3F39C", x"3F3DA", x"3F417", x"3F454", x"3F491", x"3F4CC", x"3F507", x"3F542", x"3F57B", x"3F5B4", x"3F5ED", x"3F625", x"3F65C", x"3F693", x"3F6C9", x"3F6FF", x"3F734", x"3F768", x"3F79C", x"3F7CF", x"3F801", x"3F833", x"3F864", x"3F895", x"3F8C5", x"3F8F4", x"3F923", x"3F951", x"3F97F", x"3F9AC", x"3F9D8", x"3FA04", x"3FA2F", x"3FA59", x"3FA83", x"3FAAC", x"3FAD5", x"3FAFD", x"3FB24", x"3FB4B", x"3FB71", x"3FB97", x"3FBBC", x"3FBE0", x"3FC04", x"3FC27", x"3FC4A", x"3FC6B", x"3FC8D", x"3FCAD", x"3FCCD", x"3FCED", x"3FD0C", x"3FD2A", x"3FD47", x"3FD64", x"3FD81", x"3FD9C", x"3FDB8", x"3FDD2", x"3FDEC", x"3FE05", x"3FE1E", x"3FE36", x"3FE4D", x"3FE64", x"3FE7A", x"3FE90", x"3FEA5", x"3FEB9", x"3FECD", x"3FEE0", x"3FEF3", x"3FF05", x"3FF16", x"3FF26", x"3FF36", x"3FF46", x"3FF55", x"3FF63", x"3FF70", x"3FF7D", x"3FF8A", x"3FF95", x"3FFA1", x"3FFAB", x"3FFB5", x"3FFBE", x"3FFC7", x"3FFCF", x"3FFD6", x"3FFDD", x"3FFE3", x"3FFE9", x"3FFEE", x"3FFF2", x"3FFF6", x"3FFF9", x"3FFFB", x"3FFFD", x"3FFFE", x"3FFFF" ); begin sine <= std_logic_vector(sine_sum(sine_sum'high-1 downto sine_sum'high-sine'high-1)); index_1 <= UNSIGNED(phase(phase'high downto phase'high-11)); index_2 <= UNSIGNED(phase(phase'high downto phase'high-11))+1; clk_proc: process(clk) begin if rising_edge(clk) then -- Sage 4 - sine_sum <= sine_mult_1 + sine_mult_2; -- Pipeline stage 3 - generate the final value sine_mult_1 <= sine_1 * frac_1; sine_mult_2 <= sine_2 * frac_2; -- Pipeline state 2 - look up the values in the table case quad_1 is when "00" => sine_1 <= midrange+mem(to_integer(entry_1)); when "01" => sine_1 <= midrange+mem(to_integer(entry_1)); when "10" => sine_1 <= midrange-mem(to_integer(entry_1)); when others => sine_1 <= midrange-mem(to_integer(entry_1)); end case; case quad_2 is when "00" => sine_2 <= midrange+mem(to_integer(entry_2)); when "01" => sine_2 <= midrange+mem(to_integer(entry_2)); when "10" => sine_2 <= midrange-mem(to_integer(entry_2)); when others => sine_2 <= midrange-mem(to_integer(entry_2)); end case; frac_1 <= frac_max - frac; frac_2 <= "0" & frac; -- Pipeline state 1 - break out the phase components into table indexes quad_1 <= index_1(11 downto 10); if index_1(10) = '0' then entry_1 <= index_1(9 downto 0); else entry_1 <= table_max - index_1(9 downto 0); end if; quad_2 <= index_2(11 downto 10); if index_2(10) = '0' then entry_2 <= index_2(9 downto 0); else entry_2 <= table_max - index_2(9 downto 0); end if; frac <= unsigned(phase(phase'high-12 downto 0)); end if; end process; end Behavioral;
  10. This code calculates sin() and cos() using CORDIC, and compares the results with that of the floating point library. The input angle is scaled so 2^24 is the full circle. #include "stdafx.h" #include <stdio.h> #include <math.h> #include <stdint.h> #define PI (3.14159265358979323846) #define FULL_CIRCLE (1<<24) #define EIGHTH_CIRCLE (FULL_CIRCLE/8) #define QUARTER_CIRCLE (FULL_CIRCLE/4) #define HALF_CIRCLE (FULL_CIRCLE/2) #define CORDIC_REPS (30) #define BITS (30) int64_t initial; double angles[CORDIC_REPS]; /**************************************************************** * Calculate the values required for CORDIC sin()/cos() function ***************************************************************/ void setup(void) { int i; double scale = pow(0.5, 0.5); for (i = 0; i < CORDIC_REPS; i++) { double angle = atan(1.0 / pow(2, i + 1)); angles[i] = FULL_CIRCLE angle / (2 PI); scale *= cos(angle); printf("angle[%i] = %13.9f\n", i, angles[i]); } initial = (int64_t)(scale*pow(2.0, BITS)); } /*************************************************************** * Cordic routine to calculate Sine and Cosine for angles * from 0.0 to 2*PI **************************************************************/ void cordic_sine_cosine(double z, int64_t& s, int64_t& c) { int i, flip_sine_sign = 0, flip_cos_sign = 0; int64_t x = initial, y = initial; if (z > HALF_CIRCLE) { z = FULL_CIRCLE - z; flip_sine_sign = 1; } if (z > QUARTER_CIRCLE) { z = HALF_CIRCLE - z; flip_cos_sign = 1; } z -= EIGHTH_CIRCLE; for (i = 0; i < CORDIC_REPS; i++) { int64_t tx = (x + ((int64_t)1 << i)) >> (i + 1); int64_t ty = (y + ((int64_t)1 << i)) >> (i + 1); x -= (z > 0 ? ty : -ty); y += (z > 0 ? tx : -tx); z -= (z > 0 ? angles[i] : -angles[i]); } c = flip_cos_sign ? -x : x; s = flip_sine_sign ? -y : y; } /**************************************************************/ int main(int argc, char *argv[]) { double a = 0.8, max = 0.0; double total_e = 0.0; int count = 0; setup(); for (a = 0; a < FULL_CIRCLE; a++) { int64_t s, c; double es, ec; cordic_sine_cosine(a, s, c); es = s - (int64_t)(sin(a*(2 * PI / FULL_CIRCLE))*(pow(2, BITS))); ec = c - (int64_t)(cos(a*(2 * PI / FULL_CIRCLE))*(pow(2, BITS))); if (es > 0) total_e += es; else total_e -= es; if (ec > 0) total_e += ec; else total_e -= ec; if (max < es) max = es; if (max < -es) max = -es; if (max < ec) max = ec; if (max < -ec) max = -ec; count++; } printf("Error is %13.11f per calcuation out of +/-%f\n", total_e / count, pow(2, BITS)); printf("Max error is %13.11f\n", max); return 0; } Source VHDL: cordic_sin_cos.vhd library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity cordic_sin_cos is Port ( clk : in STD_LOGIC; angle : in STD_LOGIC_VECTOR (23 downto 0); signed_sin : out STD_LOGIC_VECTOR (23 downto 0) := (others => '0'); signed_cos : out STD_LOGIC_VECTOR (23 downto 0) := (others => '0')); end cordic_sin_cos; architecture Behavioral of cordic_sin_cos is constant stages : natural := 26; constant calc_bits : natural := 28; constant z_bits : natural := 29; -- Angles for the CORDIC algorithm in fixed decimal (eg. 0x4b90147 ~= atan(0.5)) type a_angles is array(0 to stages) of signed(z_bits-2 downto 0); constant angles : a_angles := ( x"4b90147", x"27ece16", x"1444475", x"0a2c350", x"05175f8", x"028bd87", x"0145f15", x"00a2f94", x"00517cb", x"0028be6", x"00145f3", x"000a2f9", x"000517c", x"00028be", x"000145f", x"0000a2f", x"0000517", x"000028b", x"0000145", x"00000a2", x"0000051", x"0000028", x"0000014", x"000000a", x"0000005", x"0000002", x"0000001"); -- Adjusted to give full scale of +0x7FFFF & -0x7FFFF constant initial : signed(calc_bits-1 downto 0) := x"4dba76c"; -- Constants for quadrant calulations constant quarter_turn : signed(z_bits-1 downto 0) := "10000" & x"000000"; constant eigth_turn : signed(z_bits-1 downto 0) := "01000" & x"000000"; constant zero : signed(signed_sin'high downto 0) := (others => '0'); signal quadrant_angle : signed(z_bits-1 downto 0) := (others => '0'); -- Pipeline for holding the quadrant information signal flip_cos : std_logic_vector(stages+1 downto 0); signal flip_sin : std_logic_vector(stages+1 downto 0); -- Pipeline for CORDIC X, Y & Z state variables positions type a_x_or_y is array(0 to stages+1) of signed(calc_bits-1 downto 0); type a_z is array(0 to stages+1) of signed(z_bits-1 downto 0); signal x : a_x_or_y := (0 => initial, others => (others => '0')); signal y : a_x_or_y := (0 => initial, others => (others => '0')); signal z : a_z := (others => (others => '0')); begin quadrant_angle(quadrant_angle'high-1 downto quadrant_angle'high-angle'high+1) <= signed(angle(angle'high-2 downto 0)); process(clk) begin if rising_edge(clk) then -- The Output stages if flip_sin(stages+1) = '0' then signed_sin <= STD_LOGIC_VECTOR (zero + y(stages+1)(calc_bits-1 downto calc_bits-signed_sin'length)); else signed_sin <= STD_LOGIC_VECTOR (zero - y(stages+1)(calc_bits-1 downto calc_bits-signed_sin'length)); end if; if flip_cos(stages+1) = '0' then signed_cos <= STD_LOGIC_VECTOR (zero + x(stages+1)(calc_bits-1 downto calc_bits-signed_cos'length)); else signed_cos <= STD_LOGIC_VECTOR (zero - x(stages+1)(calc_bits-1 downto calc_bits-signed_cos'length)); end if; -- The actual CORDIC stages for i in 0 to stages loop if z(i)(z_bits-1) = '0' then x(i+1) <= x(i) - resize(y(i)(calc_bits-1 downto i+1),calc_bits); y(i+1) <= y(i) + resize(x(i)(calc_bits-1 downto i+1),calc_bits); z(i+1) <= z(i) - angles(i); else x(i+1) <= x(i) + resize(y(i)(calc_bits-1 downto i+1),calc_bits); y(i+1) <= y(i) - resize(x(i)(calc_bits-1 downto i+1),calc_bits); z(i+1) <= z(i) + angles(i); end if; flip_sin(i+1) <= flip_sin(i); flip_cos(i+1) <= flip_cos(i); end loop; -- Setup for the CORDIC algorithm, which only works on the first quadrant of a circle case angle(angle'high downto angle'high-1) is when "00" => flip_sin(0) <= '0'; flip_cos(0) <= '0'; z(0) <= quadrant_angle - eigth_turn; when "01" => flip_sin(0) <= '0'; flip_cos(0) <= '1'; z(0) <= quarter_turn - quadrant_angle - eigth_turn; when "10" => flip_sin(0) <= '1'; flip_cos(0) <= '1'; z(0) <= quadrant_angle - eigth_turn; when others => flip_sin(0) <= '1'; flip_cos(0) <= '0'; z(0) <= quarter_turn - quadrant_angle - eigth_turn; end case; end if; end process; end Behavioral;
  11. Я подключился к отдельному DDR порту и подаю клок на него от отдельной PLL. Частота 108 МГц. Запись и чтение данных происходит правильно. Плата de10nano
  12. Другое странное поведение: clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start1); //usleep(100); struct timespec temp; temp.tv_sec=0; temp.tv_nsec=1000000; nanosleep(&temp, NULL); clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &stop1); result = (stop1.tv_sec - start1.tv_sec) * 1e6 + (stop1.tv_nsec - start1.tv_nsec) / 1e3; printf("Time of sleep operation - %.6f \n", result); показывает Time of sleep operation - 15.620000 т.е. 15 мкс, хотя задано 1000 мкс через нс
  13. Еще один тест: clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start1); usleep(100); сlock_gettime(CLOCK_PROCESS_CPUTIME_ID, &stop1); result = (stop1.tv_sec - start1.tv_sec) * 1e6 + (stop1.tv_nsec - start1.tv_nsec) / 1e3; printf("Time of sleep operation - %.6f \n", result); возвращает Time of sleep operation - 14.140000, т.е. 14 мкс.
  14. Возможно, да: resolution depends on the implementation, so do not always expect to get nanosecond precision. The clock_getres system call returns the resolution of the specified clock. This is informational data since you do not need to apply any scaling factors to data returned by clock_gettime: the values are in seconds and nanoseconds. http://www.zonevii.com/416/notes/c-tutorials/gettime.html
  15. Собрал qsys систему для SoC (вложение). Написал под линукс программу управления на базе API. Модуль sgdma переписывает данные из DDR памяти в блочную память. Измерение времени работает с такой же функцией что по ссылке У меня выходит чтение из ddr и запись в блочную память 78 мкс. Но это же время получается не зависимо что переписываю 100 32битных слов что 2048 32битных слов. Одно и тоже время и такое большое. Не могу понять почему??? Программа управления: //Scatter Gather DMA controller 2 printf( "\n\n------------- Scatter DMA 2---------------\n\n" ); //create descriptors in the mapped memory struct alt_avalon_sgdma_packed *sgdma_desc01=sdram_16MB_add; struct alt_avalon_sgdma_packed *sgdma_desc02=sdram_16MB_add+sizeof(struct alt_avalon_sgdma_packed); struct alt_avalon_sgdma_packed *sgdma_desc03=sdram_16MB_add+2*sizeof(struct alt_avalon_sgdma_packed); struct alt_avalon_sgdma_packed *sgdma_desc_empty0=sdram_16MB_add+3*sizeof(struct alt_avalon_sgdma_packed); //Address to the physical space void* sgdma_desc1_phys0=(void*)SDRAM_16_BASE; void* sgdma_desc2_phys0=(void*)SDRAM_16_BASE+sizeof(struct alt_avalon_sgdma_packed); void* sgdma_desc3_phys0=(void*)SDRAM_16_BASE+2*sizeof(struct alt_avalon_sgdma_packed); void* sgdma_desc_empty_phys0=(void*)SDRAM_16_BASE+3*sizeof(struct alt_avalon_sgdma_packed); //configure the descriptor initDescriptor(sgdma_desc01,(void*)SDRAM_64_BASE,(void*)(ONCHIP_MEMORY2_1_BASE), sgdma_desc_empty_phys0,4*2048, //sgdma_desc2_phys ( _SGDMA_DESC_CTRMAP_OWNED_BY_HW)); initDescriptor(sgdma_desc_empty0,NULL,NULL, sgdma_desc_empty_phys0,0, (_SGDMA_DESC_CTRMAP_WRITE_FIXED_ADDRESS)); //map memory of the control register h2p_lw_sgdma_addr=virtual_base + ( ( unsigned long )( ALT_LWFPGASLVS_OFST + 0x100 ) & ( unsigned long)( HW_REGS_MASK ) ); ////fill the data space for (long int i=0;i<2048; i++){ *((uint32_t *)sdram_64MB_add+i)= 2048 - i; } //init the SGDMA controller init_sgdma(_SGDMA_CTR_IE_CHAIN_COMPLETED); debugPrintRegister(); //set the address of the descriptor setDescriptor(sgdma_desc1_phys0); // start measurement struct timespec start1, stop1; //clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start1); ///////////////////////////////////////////////// //start the transfer setControlReg(_SGDMA_CTR_IE_CHAIN_COMPLETED|_SGDMA_CTR_RUN); //debugPrintRegister(); usleep(100); //wait until transfer is complete waitFinish(); //for (long int i=0;i<256; i++){ //printf( "%d\n", *((uint32_t *)sdram_64MB_add+i)); // } //debugPrintDescriptorStatus(sgdma_desc01); //stop the core by clearing the run register setControlReg(_SGDMA_CTR_IE_CHAIN_COMPLETED); setvbuf(stdout, NULL, _IONBF, 0); clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &stop1); printf("Stop - %d\n", stop1.tv_nsec); printf("Start - %d\n", start1.tv_nsec); double result = (stop1.tv_sec - start1.tv_sec) * 1e6 + (stop1.tv_nsec - start1.tv_nsec) / 1e3; printf("Time of SDRAM operation - %.6f \n", result); //debugPrintDescriptorStatus(sgdma_desc01); printf( "/*///////////////////*/////////////////*/ \n"); for (long int i=0;i<256; i++){ printf( "%d\n", *((uint32_t *)sdram_64MB_add+i)); } printf( "////////////////////////////////////// \n"); for (int i=0;i<100;i++){ printf( "%d\n", *((uint32_t*)h2p_rom1_addr+i)); } // read results from block RAM for (int i = 0; i < 100; i++) { uint32_t val = *((uint32_t*)(h2p_rom1_addr+i)); if (val != (100-i)) printf("Error at iteration %d - the value is %d while %d expected\n", i, val, (100-i)); } soc_system.qsys
  16. Разместил ссылку в ветке "Ссылки на готовые описания модулей на форуме"
×
×
  • Создать...