Golikov 0 23 мая, 2017 Опубликовано 23 мая, 2017 · Жалоба можем вам только разрешить это сделать:) можно описать память reg [ADDR_S - 1 : 0] Addr; reg [DATA_S - 1 : 0] Data [(2 ** ADDR_S) - 1 : 0]; always @(posedge clk) Addr <= addr_in; always @(posedge clk) if(write_en) Data[addr_in] <= data_in; assign data_out = Data[Addr]; это обычная память которая в 99% случаев автоматически укладывается синтезатором в специализированные блоки если они есть, или делается на регистрах если их нет. Можно явно использовать блоки Можно использовать мего-функцию генератор. Как вам больше нравится. Можно найти шаблон описания памяти от производителя, в том числе и 2 портовой, если надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scorpein 0 24 мая, 2017 Опубликовано 24 мая, 2017 · Жалоба можем вам только разрешить это сделать:) можно описать память reg [ADDR_S - 1 : 0] Addr; reg [DATA_S - 1 : 0] Data [(2 ** ADDR_S) - 1 : 0]; always @(posedge clk) Addr <= addr_in; always @(posedge clk) if(write_en) Data[addr_in] <= data_in; assign data_out = Data[Addr]; это обычная память которая в 99% случаев автоматически укладывается синтезатором в специализированные блоки если они есть, или делается на регистрах если их нет. Можно явно использовать блоки Можно использовать мего-функцию генератор. Как вам больше нравится. Можно найти шаблон описания памяти от производителя, в том числе и 2 портовой, если надо. Ого! Спасибо! А на каком языке этот код? :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 24 мая, 2017 Опубликовано 24 мая, 2017 · Жалоба на английском:) это Verilog Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scorpein 0 24 мая, 2017 Опубликовано 24 мая, 2017 (изменено) · Жалоба на английском:) ну не на русском точно)) не сочтите за наглость, но можно ли такое написать на VHDL? Просто Verilog я вообще не знаю, а VHDL сейчас изучаю и прошивка на нём.. Изменено 24 мая, 2017 пользователем scorpein Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 24 мая, 2017 Опубликовано 24 мая, 2017 · Жалоба process(all) begin if (clk'event and clk = '1') then Addr <= addr_in; if(we) then Data[addr_in] <= data_in; end if; end if; end process; process(all) data_out <= Data[Addr]; end process; вроде как то так, я давно на VHDL не писал Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scorpein 0 25 мая, 2017 Опубликовано 25 мая, 2017 (изменено) · Жалоба process(all) begin if (clk'event and clk = '1') then Addr <= addr_in; if(we) then Data[addr_in] <= data_in; end if; end if; end process; process(all) data_out <= Data[Addr]; end process; вроде как то так, я давно на VHDL не писал Благодарю!!!!!! Шас буду смотреть, что получится... Не могли бы вы дать краткое описание этого кода, потому как застрял на объекте "we", ну и остальное, чтобы не затормозить сильно.. Изменено 25 мая, 2017 пользователем scorpein Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
1891ВМ12Я 0 25 мая, 2017 Опубликовано 25 мая, 2017 · Жалоба Если затруднения с ПЛИС, то может сделать этот простой интерфейс на микроконтроллере? Тайминги позволят? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 25 мая, 2017 Опубликовано 25 мая, 2017 · Жалоба we - write enable внешний сигнал разрешения записи в память, если он один то то что на входе data_in попадает в ячейку с номером addr_in. data_in - вход шины данных addr_in - вход шины адреса на data_out выдаются данные из ячейки с номером addr_in, но выдаются на следующем такте (так в памятях принято). то есть выставляете addr_in, и на следующем такте можете забирать данные, а если хотите записать, то выставляете addr_in, data_in, и we и данные будут записаны как то так... на самом деле в книжке должно быть написано как память описывается. Если такой код вызывает затруднения, то надо сделать шаг назад и еще почитать основы, чуть сильнее Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scorpein 0 25 мая, 2017 Опубликовано 25 мая, 2017 · Жалоба Если затруднения с ПЛИС, то может сделать этот простой интерфейс на микроконтроллере? Тайминги позволят? Дело в том, что я получаю на ПЛИС данные с шины LPC, а далее мне необходимо их передать на МК. Так как частоты шины и МК не совпадают, появилась идея создания некой буферной памяти, откуда данные будут уже на частоте МК передаваться. we - write enable внешний сигнал разрешения записи в память, если он один то то что на входе data_in попадает в ячейку с номером addr_in. data_in - вход шины данных addr_in - вход шины адреса на data_out выдаются данные из ячейки с номером addr_in, но выдаются на следующем такте (так в памятях принято). то есть выставляете addr_in, и на следующем такте можете забирать данные, а если хотите записать, то выставляете addr_in, data_in, и we и данные будут записаны как то так... на самом деле в книжке должно быть написано как память описывается. Если такой код вызывает затруднения, то надо сделать шаг назад и еще почитать основы, чуть сильнее Спасибо большое за пояснения! Был бы рад сделать шаг назад, но время играет против меня.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scorpein 0 25 мая, 2017 Опубликовано 25 мая, 2017 (изменено) · Жалоба Я попробовал выделить память "штатными" средствами, которые предлагает сам Quartus. Пожалуйста посмотрите код... library IEEE; use IEEE.STD_LOGIC_1164.ALL; --use IEEE.STD_LOGIC_ARITH.ALL; --use IEEE.STD_LOGIC_UNSIGNED.ALL; entity LPC_IOW80 is -- разрядность шин generic ( DATA_WIDTH : natural := 3; ADDR_WIDTH : natural := 5 ); Port ( lclk: in std_logic; -- LPC: 33MHz clock (rising edge) lframe_n: in std_logic; -- LPC: frame, active low lreset_n: in std_logic; -- LPC: reset, active low lad: in std_logic_vector(3 downto 0); -- LPC: multiplexed bus --назначение портов для памяти addr : in natural range 0 to 2**ADDR_WIDTH - 9; we : in std_logic := '1'; q : out std_logic_vector((2**DATA_WIDTH -5) downto 0) ); end LPC_IOW80; architecture RTL of LPC_IOW80 is type LPC_State_Type is ( IDLE, -- Waiting for a start condition START, -- Start condition detected WADDN3, -- I/O write address nibble 3 (A15..A12) WADDN2, -- I/O write address nibble 2 (A11..A8 ) WADDN1, -- I/O write address nibble 1 (A7..A4) WADDN0, -- I/O write address nibble 0 (A3-A0) WDATN1, -- I/O write data nibble 0 (D7..D4) WDATN0, -- I/O write data nibble 1 (D3..D0) WHTAR0, -- I/O write host turn around phase 0 WHTAR1, -- I/O write host turn around phase 1 WSYNC, -- I/O write sync WPTAR -- I/O write peripheral turn around ); signal LPC_State: LPC_State_Type; signal lframe_nreg: std_logic; -- LPC frame register signal lad_rin: std_logic_vector(lad'range); -- LPC input registers signal W_Data: std_logic_vector(7 downto 0); -- LPC input Post Code -- создание массивов и объявление RAM -- Build a 2-D array type for the RAM subtype word_t is std_logic_vector((2**DATA_WIDTH-5) downto 0); type memory_t is array(2**ADDR_WIDTH-9 downto 0) of word_t; -- Declare the RAM signal. signal ram : memory_t; -- Register to hold the address signal addr_reg : natural range 0 to 2**ADDR_WIDTH-9; begin --------------------------------------------------------------------------- -- LPC bidirectional pins definition. --------------------------------------------------------------------------- -- Input register to get some timing margin P_input_register: process(lclk) begin if (lclk'event and lclk='1') then lad_rin <= lad; lframe_nreg <= lframe_n; end if; end process; --------------------------------------------------------------------------- -- LPC state machine -- LPC_State value is actually one clock cycle late. --------------------------------------------------------------------------- P_LPC_StatMachine: process(lclk) begin if (lclk'event and lclk='1') then -- Synchronous reset if (lreset_n = '0') then LPC_State <= IDLE; W_Data(7 downto 0) <= "00000000"; -- init. both displays to all on else case LPC_State is -- Looking for a START condition when IDLE => if (lframe_nreg = '0') and (lad_rin = "0000") then LPC_State <= START; -- START condition detected end if; -- Skip extra cycles on START frame -- (can be many clock cycles) -- and then, check for I/O write transaction when START => if (lframe_nreg = '0') then -- frame still asserted if (lad_rin /= "0000") then LPC_State <= IDLE; -- unsupported start code end if; else if (lad_rin(3 downto 1) = "001") then LPC_State <= WADDN3; -- I/O write detected else LPC_State <= IDLE; -- unsupported command end if; end if; -- -------------------------------- -- I/O write transaction processing -- -------------------------------- when WADDN3 => -- Write Data Address Nibble 3 -- Find next state if (lframe_nreg = '0') or (lad_rin /= "0000") then LPC_State <= IDLE; -- abort cycle, bad frame -- or address mismatch else LPC_State <= WADDN2; end if; when WADDN2 => -- Write Data Address Nibble 2 -- Find next state if (lframe_nreg = '0') or (lad_rin /= "0000") then LPC_State <= IDLE; -- abort cycle, bad frame -- or address mismatch else LPC_State <= WADDN1; end if; when WADDN1 => -- Write Data Address Nibble 1 -- Find next state if (lframe_nreg = '0') or (lad_rin /= "1000") then LPC_State <= IDLE; -- abort cycle, bad frame -- or address mismatch else LPC_State <= WADDN0; end if; when WADDN0 => -- Write Data Address Nibble 0 -- Find next state if (lframe_nreg = '0') or (lad_rin /= "0000") then LPC_State <= IDLE; -- abort cycle, bad frame -- or address mismatch else -- Write address valid. Subsequent Data displays. LPC_State <= WDATN0; -- Next state will get -- first data nibble end if; when WDATN0 => -- Data LSN (Least Significant Nibble)is -- sent first W_Data(3 downto 0) <= lad_rin; -- latch data (LSN) if (lframe_nreg = '1') then LPC_State <= WDATN1; -- Next state gets -- 2nd data nibble else LPC_State <= IDLE; end if; when WDATN1 => -- Data MSN (Most Significant Nibble) W_Data(7 downto 4) <= lad_rin; -- latch data (MSN) if (lframe_nreg = '1') then LPC_State <= WHTAR0; else LPC_State <= IDLE; end if; when WHTAR0 => -- Write Data Turn Around Cycle 0 if (lframe_nreg = '1') and (lad_rin = "1111") then LPC_State <= WHTAR1; else LPC_State <= IDLE; end if; when WHTAR1 => -- Write Data Turn Around Cycle 1 if (lframe_nreg = '1') then LPC_State <= WSYNC; else LPC_State <= IDLE; end if; when WSYNC => -- Write Data Sync Cycle -- Note: No device to respond with a synch at I\O addr -- 080h. Therefore bus should time out and abort. -- State ==> to IDLE if (lframe_nreg = '1') then LPC_State <= WPTAR; else LPC_State <= IDLE; end if; when WPTAR => -- Write Data Final Turn Around Cycle -- (not needed -- see WSYNC) LPC_State <= IDLE; -- I/O write cycle end when others => LPC_State <= IDLE; -- all other cases end case; end if; end if; end process; --данные с шины по тетраде помещаются в ram process(lclk) begin if(rising_edge(lclk)) then if(we = '1') then ram(addr) <= W_data(7 downto 4); end if; -- Register the address for reading addr_reg <= addr; end if; if(rising_edge(lclk)) then if(we = '1') then ram(addr) <= W_data(3 downto 0); end if; -- Register the address for reading addr_reg <= addr; end if; end process; --собственно вывод данных q <= ram(addr_reg); end RTL; Изменено 25 мая, 2017 пользователем scorpein Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scorpein 0 26 мая, 2017 Опубликовано 26 мая, 2017 (изменено) · Жалоба Только что предложили использовать внешнюю RAM-память. Модуль на 128 кб. Должны подвезти. Наверное, будет лучше использовать такой вариант... Привезли память UM61256K-15 (аналог IS61C256AH). Теперь нужно передавать на неё байты данных с ПЛИС и считывать их МК. Подскажите по этой теме? Изменено 26 мая, 2017 пользователем scorpein Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 26 мая, 2017 Опубликовано 26 мая, 2017 · Жалоба Обожаю такие решения%) Я бы предложил вам использовать профессиональных инженеров, их найти труднее чем СРАМ, но и выхлоп будет лучше. Подсказываю по теме. Берет и используете. Память однопортовая, поэтому доступ к ней будет иметь одновременно только 1 устройство. В вашем случае это будет ПЛИС. Поэтому в ПЛИС вам надо организовать механизм арбитража доступа к памяти. Чтобы плис могла писать в нее когда ей надо, и предоставлять процессору доступ на чтение когда ему надо. Внутри вы могли сделать 2 портовую память и лазить в нее без арбитража, а тут наслаждайтесь проектированием:) Вы интерфейс проц - плис то наладили? Может с него начать, а не с памяти? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scorpein 0 26 мая, 2017 Опубликовано 26 мая, 2017 · Жалоба Обожаю такие решения%) Я бы предложил вам использовать профессиональных инженеров, их найти труднее чем СРАМ, но и выхлоп будет лучше. Подсказываю по теме. Берет и используете. Память однопортовая, поэтому доступ к ней будет иметь одновременно только 1 устройство. В вашем случае это будет ПЛИС. Поэтому в ПЛИС вам надо организовать механизм арбитража доступа к памяти. Чтобы плис могла писать в нее когда ей надо, и предоставлять процессору доступ на чтение когда ему надо. Внутри вы могли сделать 2 портовую память и лазить в нее без арбитража, а тут наслаждайтесь проектированием:) Вы интерфейс проц - плис то наладили? Может с него начать, а не с памяти? Использовать внешнюю память приходится из-за малого числа вентилей в моём ПЛИС - всего 240. Та прошивка, которую выкладывал выше забила его на 95%. Сейчас как раз обдумываю арбитраж. С интерфейсом ещё ничего не решилось. :laughing: На просторах интернета в основном решения передачи от МК к ПЛИСу, не уверен, что это мне подойдёт. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 26 мая, 2017 Опубликовано 26 мая, 2017 · Жалоба так это CPLD что ли? Ну так можете бросать это дело... CPLD у вас может выполнять только функцию преобразования SPI в параллельную шину для памяти от проца, больше его ни на что не хватит... С другой стороны можно взять любой АРМ и FRAM к нему как внешнюю оперативку и всех делов... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scorpein 0 26 мая, 2017 Опубликовано 26 мая, 2017 · Жалоба функцию преобразования SPI в параллельную шину для памяти от проца Прошу прощения, но не я не совсем понял, в чём смысл этой функции, относительно задачи.. Менять устройство, к сожалению, уже невозможно. Нужно делать с этим. :laughing: Почему Quartus ругается на io[addr] <= W_data(7 downto 0); или Data[addr_in] <= data_in; Постоянно ошибка Error (10500): VHDL syntax error at LPC_IOW80.vhd(185) near text "<="; expecting "(", or "'", or "." :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться