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

artyombn

Участник
  • Публикаций

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

  • Посещение

Репутация

0 Обычный
  1. День добрый уважаемые форумчане. Столкнулся с проблемой недопонимания, не могу понять как мне полноценно построить логику для блока памяти. Есть ячейка памяти: [attachment=107666:1.png]. Необходимо разработать логику для управления блоком, состоящим из 8 ячеек. 1х8. Блок устройства я представил следующим образом: [attachment=107667:3.png] Din - порт для ввода данных. R/W - Read/Write - чтение/запись. A0-A1 - входи дешифратора. CLK - синхроимпульс. Дешифратор я собрал 2х4 для тестирования схемы (чтобы пока не нагружать дешифратором 3х8) [attachment=107668:deshh2.PNG] после начал соединять дешифратор с моими ячейками [attachment=107669:desh.png] Результат симулирования: [attachment=107670:2.png] Сверху вниз: 1) выход первого порта дешифратора (out 1) 2) выход второго порта дешифратора (out 4) 3) выход схемы (BL) Разбил по парам выходные импульсы дешифратора, 1 с 4 и 2 с 3 именно по временным диапазонам, т.к. выход у нас один и наложение будет жуткое. Вот результат по 2му и третьему импульсам: [attachment=107671:332.png] Тест дешифратора на этом закончил. Вроде все работает. Напряжение 1.2435 В, усилители не ставил, поэтому пока что работаю с таким выходным напряжением. После чего мне нужно внедрить разрешающий сигнал на запись или чтение. Но встает вопрос как это сделать? Мне во время записи нужно чтобы на BL записалось то, что подали на Din, и в этот же момент должно сработать WL для записи, причем нужно проверить отсутствие сигнала на nBL. Затем нужно переключить на чтение и уже запустить проверку на отсутствие сигналов как на BL, так и на nBL в добавку все по такту. Чтоб читалось нужно подать противоположный сигнал записи, и в этот момент подать на WL единицу. WL можем контролировать дешифратором, для этого я его и сделал. А вот разобраться с этим разрешающим сигналом и процессами которые будут происходить внутри всей схемы я не могу. Может есть люди которые смогут помочь разобраться? Ибо время поджимает, а я фиг знает как дальше делать. Спасибо.
  2. Цитата(Golikov A. @ May 23 2017, 09:26) Коль вы в начале пути, может стоит сразу свернуть на верную дорожку verilog:)? я слышал об этом языке и не 1 раз) а что на VHDL никто уже не работает?
  3. Цитата(Dr.Alex @ May 22 2017, 22:36) Эхе-хе. Вот вам кот. а я даже и не подумал об этом: Код bp <= "0000000" & b & "0"; простое и легкое выражение убивало двух зайцев, а я даже и не сообразил так сделать. спасибо вам огромное за помощь. видимо мне нужно ещё больше практики и чтения.
  4. Цитата(Golikov A. @ May 22 2017, 12:50) Хотите экономить каждый так. Меняйте мышление. Вы сейчас думаете моментом сразу после фронта клока. Выставляете данные для этого момента, и как результат получаете все свои ответы на следующем такте. А думать надо моментом сразу после фронта, и выставлять данные для следующего. то есть мне надо работать по спаду такта? можете показать самый элементарный пример, где работа идет моментом после фронта? Цитата(Golikov A. @ May 22 2017, 12:50) То есть на самом деле вам нужно создавать комбинаторную часть схемы, а в регистры просто щелкать результат. сейчас вы сохраняете операнды по сигналу загрузки и начинаете считать. При этом операнды и сигнал загрузки появляются появились сразу после фронта. И вы можете на следующем же фронте уже сохранить первый такт счета. я не понимаю как должна выглядеть эта комбинаторная схема. если бы я понимал поболее, я бы, наверное, понял о чем вы ведете речь. все элементарные описания по vhdl мне мало помогают, хотя я штудирую их понемногу.
  5. хочется сэкономить все, до последнего такта. поэтому я начал прописывать действия при i=0 в load. но не пойму почему мне не выдает результат bp. когда load = 1 и по такту мы вроде bp записали, потом его используем. оно же никуда не девается. а на вейформе оно неопределенно. Кодlibrary IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_unsigned.all; use IEEE.NUMERIC_STD.all; entity test is     port(     clk, r: in std_logic;     a : in std_logic_vector(7 downto 0);     b : in std_logic_vector(7 downto 0);     p : out std_logic_vector(15 downto 0);     load: in std_logic     );      end test; architecture test of test is signal pv: std_logic_vector(15 downto 0):=(others => '0'); signal bp: std_logic_vector(15 downto 0); signal i : integer range 0 to 8; begin     process begin   wait until clk'event and clk = '1';             if load = '1' then         bp<= "00000000" & b;         i <= 0;             if a(i) = '1' then                 pv<= "00000000" & b;             else             pv <= (others => '0');             end if;             bp<=bp(14 downto 0) & '0';                 i<=1;             else               if i<8 then                     if a(i) = '1' then                 pv<= pv+bp;                 end if;                 bp<=bp(14 downto 0) & '0';                 i<=i+1;         end if;         p<=pv;         end if;         end process;   end test; Цитатано не пойму почему мне не выдает результат bp. когда load = 1 и по такту мы вроде bp записали, потом его используем. оно же никуда не девается. а на вейформе оно неопределенно. хотя я понял почему. мы как записываем, так и сдвигаем одновременно bp в одном такте.сейчас попробую исправить p.s. а это вообще возможно?? что-то у меня не получается.
  6. вот переписанный код Кодlibrary IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_unsigned.all; use IEEE.NUMERIC_STD.all; entity test is     port(     clk, r: in std_logic;     a : in std_logic_vector(7 downto 0);     b : in std_logic_vector(7 downto 0);     p : out std_logic_vector(15 downto 0);     load: in std_logic     );      end test; --}} End of automatically maintained section architecture test of test is signal pv: std_logic_vector(15 downto 0):=(others => '0'); signal bp: std_logic_vector(15 downto 0); signal i : integer range 0 to 8; begin     process begin   wait until clk'event and clk = '1';             if load = '1' then         bp<= "00000000" & b;         i <= 0;         else               if i<8 then                 if i<=0 then                 if a(i) = '1' then                 pv<= pv+bp;                 end if;                 bp<=bp(14 downto 0) & '0';                 i<=i+1;             else                 if a(i) = '1' then                 pv<= pv+bp;                 end if;             bp<=bp(14 downto 0) & '0';                 i<=i+1;             end if;         end if;         p<=pv;         end if;         end process;   end test; вот моделирование изначально он не может понять что такое bp пока не стартанет клок. задать заранее bp мы не можем, ибо без клока ничего вообще происходить не будет. именно поэтому раньше клок у меня шел после лоад, но тогда, как вы сказали, лоад будет действительно ассинхронный. и почему pv в первый такт не стал равен bp? вроде как это условие выполняется Кодif i<8 then                 if i<=0 then                 if a(i) = '1' then                 pv<= pv+bp;                 end if; и должно попасть в первый такт Цитата(artyombn @ May 22 2017, 02:34) и почему pv в первый такт не стал равен bp? вроде как это условие выполняется Кодif i<8 then                 if i<=0 then                 if a(i) = '1' then                 pv<= pv+bp;                 end if; и должно попасть в первый такт хотя оно попадает, но во второй такт..
  7. Цитата(Dr.Alex @ May 22 2017, 01:11) Код            if i = 0             then                 что-то             end if;             что-то ещё         else             что-то ; я не понял зачем тут if i=0 ? т.е. мне каждое изменение i описывать? к примеру как я понял: Код        if i<8 then                 if i<=0 then                 if a(i) = '1' then                 pv<= pv+bp;                 end if;                 bp<=bp(14 downto 0) & '0';                 i<=i+1;             else         if i<=1 then                 if a(i) = '1' then                 pv<= pv+bp;                 end if;             bp<=bp(14 downto 0) & '0';                 i<=i+1;             end if;         end if;             end if;         end if; и ещё VHDL ругается на "wait until clk'event and clk = '1';" , с непонятной для меня ошибкой: "# Error: COMP96_0242: testt.vhd : (50, 1): Wait statement in process with explicit sensitivity list is not allowed."
  8. Цитата(Dr.Alex @ May 21 2017, 23:38) Да просто поставить условие. Если меньше чего-то, тогда инкрементируем. да, что-то сглупил в этом моменте. ЦитатаКак не доходит? Тогда данные не загрузятся (если только случайно). Он должен стоять одновременно с данными. вот результат если load не будет доходить до clk а вот результат если будет разницу не вижу. вижу задержку по такту. с одной стороны хорошо когда i на первом клоке равно 0, но тогда результат будет даже не за 9 тактов, а за 10. что ещё хуже. а нужно результат вообще за 8 тактов. Цитатаp<=pv нужно вообще вынести из процесса, один такт уйдёт. вынес из процесса. он мне показывает неопределенное состояние. скорее всего потому что pv каждый раз меняет свое значение, а я прошу вывести общую p<=pv. поэтому он и не понимает какую нужно вывести. получается просто вынести pv из процесса не получится
  9. избавился от not(i=8) Кодif load = '1' then         bp<= "00000000" & b;         else         if (clk'event and clk = '1') then                 if a(i) = '1' then                 pv<= pv+bp;                     end if;             bp<=bp(14 downto 0) & '0';                 i<=i+1;             if i<=8 then             p<=pv;             end if;             end if; но я не знаю как остановить дальнейшее увеличение i. и ещё такой вопрос. если у нас load не доходит до фронта первого такта, то задержка выхода p составляет 1 такт. если load доходит или лежит в области первого такта, то задержка на выходе p составляет 2 такта. есть ли возможность избавиться от задержки?
  10. Цитата(Dr.Alex @ May 21 2017, 15:58) Это происходит из-за верхней строчки bp<= "00000000" & b; У неё нет никаких условий, поэтому она срабатывает при любом изменении clk. Её нужно убрать, а как производить первоначальную загрузку bp — подумайте. Может быть стоит проверять условие i = 0 и тогда что-то делать? and not(i=8) тоже нужно убрать, так не пишут. таким способом записать bp не получается:Кодsignal bp: std_logic_vector(15 downto 0):="00000000" & b; поэтому создал переменную load и сделал условие. Кодif load = '1' then         bp<= "00000000" & b;         i<=0;         end if; теперь возникают 2 вопроса. как избавиться от проскока значений bp=22 и i=1, которые срабатывают в условии при clk=1? и почему срабатывает условие if a(i)='1' , при i=1 (где a(1)=0) . т.е. мы наблюдаем что при i=1 pv=bp, хотя при i=1 по коду это условие не должно выполняться и просто должен произойти сдвиг bp. хотя я нашел выход) просто прописал условие в нужном месте Кодbegin                   if r='1' then             pv<="0000000000000000";             p<=pv;                 i <= 0;         else             if load = '1' then         bp<= "00000000" & b;         i<=0;         else         if (clk'event and clk = '1' and not(i=8)) then                 if a(i) = '1' then                 pv<= pv+bp;                 end if;             bp<=bp(14 downto 0) & '0';                 i<=i+1;             p<=pv;             end if;         end if;             end if; почему нельзя писать not(i=8) при разводке в леонардо это скажется? и как остановить расчет иначе когда i достигнет 8?
  11. Цитата(Dr.Alex @ May 21 2017, 04:12) loop надо убрать. Вместо этого инкрементируйте i (1 раз за такт clk, есесно :-) и в зависимости от его значения что-то делайте. И советую избавиться от переменных (используйте только сигналы), а то соседство блокирующих и неблокирующих назначений это для начинающего верный путь запутаться и ничего не понять. loop убрал. инкрементирую i 1 раз за такт. возникает ряд вопросов. почему bp прыгает, сначала как полагается, оно равно 11, затем по единице clk становится 22 (тут произошел сдвиг влево), а затем по спаду оно становится равно опять 11. почему? оно ведь перезаписалось, и до следующего такта не должна меняться. из-за этого оно всегда будет меняться с 11 до 22. почему это условие Кодif a(i) = '1' then                 pv<= pv+bp;                 end if; работает как цикл в одном такте импульса? я не понимаю почему такое банальное описание приводит к таким результатам. где я ошибаюсь? вот код с моделированием. Кодlibrary IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_unsigned.all; use IEEE.NUMERIC_STD.all; entity test is     port(     clk, r: in std_logic;     a : in std_logic_vector(7 downto 0);     b : in std_logic_vector(7 downto 0);     p : out std_logic_vector(15 downto 0)     );      end test; --}} End of automatically maintained section architecture test of test is signal pv: std_logic_vector(15 downto 0):=(others => '0'); signal bp: std_logic_vector(15 downto 0); signal i : integer range 0 to 8; begin process(clk)     begin                   bp<= "00000000" & b;           if r='1' then             pv<="0000000000000000";             p<=pv;                 i <= 0;         else         if (clk'event and clk = '1' and not(i=8)) then                 if a(i) = '1' then                 pv<= pv+bp;                 end if;             bp<=bp(14 downto 0) & '0';                 i<=i+1;             p<=pv;         end if;             end if;         end process; end test;
  12. если смотреть на код, то тут просто в лоб a*b ) чего мне не нужно. подскажите, если вы знаете, как сделать так, чтобы мой умножитель делал каждое действие сложения по такту. наверное нужен особенный клок? вот я этого понять не могу. если просто тупо убрать цикл и попробовать прописать все условия if a(0)='1' ..... if a(1)='1'.... все равно он мне все делает за 1 такт. я не знаю как сделать чтобы каждое действие (pv+ bp и сдвиг bp влево) делалось за 1 такт.
  13. День добрый, уважаемые форумчане. Я новенький в VHDL, и первое задание мое было это восьмиразрядный тактовый умножитель . Причем не банальным способом где a*b, а иным. Немного поискав информации в интернете я нашел способ, получил умножитель в виде счетчика с регистром сдвига. В общем вот код. Кодlibrary IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_unsigned.all; entity test is     port(     clk, r: in std_logic;     a : in std_logic_vector(7 downto 0);     b : in std_logic_vector(7 downto 0);     p : out std_logic_vector(15 downto 0)     );      end test; --}} End of automatically maintained section architecture test of test is begin process(clk,r,a,b)     variable pv,bp: std_logic_vector(15 downto 0);     begin                   pv:= "0000000000000000";         bp:= "00000000" & b;         if r='1' then             pv:="0000000000000000";             p<=pv;         else         if clk'event and clk = '1' then         for i in 0 to 7 loop                 if a(i) = '1' then                 pv:= pv+bp;                     p<=pv;             end if;             bp:= bp(14 downto 0) & '0';         end loop;         end if;             end if;         end process; end test; а вот результат моделирования. Как видите все работает. Но возникает вопрос. Почему он выдает результат сразу за 1 такт, а не за 8 тактов как должно быть? ведь каждое начало цикла должно входить в 1 такт. а тут сразу весь цикл в такт входит. Но мне нужен тактовый умножитель, чтобы за каждый такт он делал сложение pv с bp и последующим сдвигом влево. Подскажите как сделать так чтобы результат умножения был за 8 тактов а не за 1. Если есть возможность, желательно подскажите на примере, так как я начинающий в этом деле на словах могу не понять. Спасибо.