Михей91 0 November 29, 2012 Posted November 29, 2012 (edited) · Report post Воспользовался ссылкой Muscat, создал файл Verilog Test Fixture, добавил кое-что из статьи, CLK и RST работают, DATA_O постоянно находится в состоянии ZZZZ, DATA_i в 0000, SEQ бежит начиная с F, A, D, 1, 6,...., 7, 8, F, т.е. по нашей последовательности. Верно? Теперь еще нужно описать UP, LOAD и OE? `timescale 1ns / 1ps module fff; // Inputs reg clk; reg rst; reg load; reg up; reg oe; reg [3:0] data_i; // Outputs wire [3:0] data_o; wire [3:0] seq; // Instantiate the Unit Under Test (UUT) generator uut ( .clk(clk), .rst(rst), .load(load), .up(up), .oe(oe), .data_i(data_i), .data_o(data_o), .seq(seq) ); initial begin // Initialize Inputs clk = 0; rst = 0; load = 0; up = 0; oe = 0; data_i = 0; // Wait 100 ns for global reset to finish #20; // Add stimulus here end always #5 clk = ! clk; event reset_trigger; //объявление событий event reset_done_trigger; // //блок формирования Reset initial begin forever begin //бесконечный цикл @ (reset_trigger); //ждем события reset_trigger @ (negedge clk); //ждем negedge clk rst = 1; //сброс @ (negedge clk); rst = 0; -> reset_done_trigger; //сигналим что reset выполнен end end //Ход симуляции initial begin: TEST_CASE #10 -> reset_trigger; //сделать ресет end endmodule Edited November 29, 2012 by Михей91 Quote Share this post Link to post Share on other sites More sharing options...
Михей91 0 November 30, 2012 Posted November 30, 2012 · Report post Показал сегодня преподавателю все эти наработки, но он сказал что это можно использовать как дополнение к работе, т.к. саму работу нужно строить именно схемами, грубо говоря в файле .sch, каждый элемент из схемы на "рис. 1" нужно построить на отдельном листе. CL-1 он обозначил за DEC, CL+1 за INC, сказал реализовать их как одноразрядный сумматор работающий в одну сторону, выглядит он так: Но именно такой элемент я не нашел, есть предположение что нужно взять элемент XOR3 ? Мультиплексор строим на элементе M2_1. Регистры на FDP, FDC. Кстати их будет 16 штук, от 0 до F? Буфер строим на BUFE. Что касается того, что мы должны получить на временной диаграмме. Нужно продемонстрировать направление счета: вверх, вниз и продемонстрировать загрузку, вот как это должно выглядеть: Первая диаграмма демонстрирует направление счета, когда UP=1 мы плюсуем, как только UP=0 начинаем считать в обратную сторону. Вторая диаграмма демонстрирует загрузку, тут я не совсем понял, мы должны задать только значение LOAD и на тот момент когда он включится DATA_I выберется само, или его тоже нужно определять руками? Quote Share this post Link to post Share on other sites More sharing options...
Muscat 0 November 30, 2012 Posted November 30, 2012 · Report post Scheme_1.sch В ISE выбирай в колонке справа "Add Source" Дальше выбираей Schematic В открывшемся поле выбирай add symbol Дальше по списку ищем компоненты, их есть там и сумматор и регистры. Не забудь добавить порты. После этого свою схему включаешь в ISE Цепляю файлик с компонентами к посту. Гугли на тему "Xilinx ISE Schematic" PS Хотел пошутить про то, что это адовый изварт и схемным вводом ПЛИС делать это умом поехать, но потом вспомнил свой курсач на ту же тему, в котором мне не разрешили заменить задачу на К155 серии на ПЛИСовский и... Ох, хорошо, что кое где уже знают, что такие Xilinx и Verilog. Quote Share this post Link to post Share on other sites More sharing options...
Михей91 0 November 30, 2012 Posted November 30, 2012 (edited) · Report post Товарищи, и еще вопрос в догонку, реализовываю попутно автомат Мура: и нужно данную комбинационную схему описать с помощью Case. Уже все возможные варианты перепробовал, ругается на синтаксис... `timescale 1ns / 1ps module mur ( input wire clk, input wire rst, input wire up, output wire [3:0] seq ); //------------------------------------------ // SEQ using Case: always @(posedge clk) case (seq) 4'h0: begin if (up == 0) 4'h0 <= 4'h1; else (up == 1) 4'h0 <= 4'hF; end // //все остальные значения // default: begin if (up == 0) 4'hF <= 4'h0; else (up == 1) 4'hF <= 4'hE; end endcase //------------------------------------------ endmodule В зависимости от того, какое значение принимает UP мы движемся либо по часовой, либо против. Но в чем ошибка, не могу разобраться... Muscat, ну как создать и цеплять схемотехнику слава богу я знаю))))) Сейчас посмотрю что прикрепили, и попытаюсь что-нибудь сделать ;) Не хочет кушать схемку: Scheme_1.sch, Line 1 : Error : Parser fatal error encouted : An exception occurred! Type:UTFDataFormatException, Message:invalid byte 2 (я) of a 2-byte sequence. И я проект на Spartan3 создаю, а у Вас aspartan3a, это критично? Edited November 30, 2012 by Михей91 Quote Share this post Link to post Share on other sites More sharing options...
Konst_777 1 November 30, 2012 Posted November 30, 2012 · Report post Показал сегодня преподавателю все эти наработки, но он сказал что это можно использовать как дополнение к работе, т.к. саму работу нужно строить именно схемами, грубо говоря в файле .sch, каждый элемент из схемы на "рис. 1" нужно построить на отдельном листе... Ну и ну... Значит, таки прав был Muscat: ...Ну тогда по пути два. Создаем модуль мультиплексор, модуль буфера, регистр и что там еще. Потом описываем их соединение, как вы делали это для элементов комбинационной логики... В этом я Вам помочь не смогу, поскольку использую только продукцию Altera :laughing: Товарищи, и еще вопрос в догонку, реализовываю попутно автомат Мура: ... и нужно данную комбинационную схему описать с помощью Case. Уже все возможные варианты перепробовал, ругается на синтаксис... Еще бы. Присваиваете константу константе. Рекомендованную книгу Pong P. Chu не изучаете. :angry2: И советам не следуете: Правильная мысль - нажать на лампочку в ISE и посмотреть примеры кода на Verilog. Там есть описания всех основных конструкций. Mur.v Quote Share this post Link to post Share on other sites More sharing options...
Михей91 0 November 30, 2012 Posted November 30, 2012 (edited) · Report post Konst_777, ну на самом то деле преподаватель этот case на доске написал, вот только дома я повторил и получил то что получил, выходит он не компетентен или на шару нам на доске пишет? А зачем нужен параметр: #(parameter BITS=4)? Почему мы задаем именно так output reg [bITS-1:0] seq, а не [3:0]? И в чем различие конструкций always @ от always @* ? Почему мы пишем условие именно так if (up), без явного присвоения up`у нуля или единицы? Edited November 30, 2012 by Михей91 Quote Share this post Link to post Share on other sites More sharing options...
Muscat 0 December 1, 2012 Posted December 1, 2012 · Report post Попробуй вот так Scheme_1.sch зачем нужен параметр: #(parameter BITS=4)? Ох, Михей. Ты на программирование был? Паскал видель? Это практически повсеместное правило, что разрядность шин задается через какой либо параметр (через generic или constant в VHDL или вот так в Verilog). Представь, что ты сделал счетчик на 4 разряда. Везде ручками написал [3:0]. В 10 местах так объявил. Или в 100, если проект большой. А потом пришел препод и сказал - а сделай ка Миха на 20 разрядов. И ты ручками начинаешь все переписывать. А так задал все порты через параметр, а потом по надобности меняешь его. Удобно же? Почему мы пишем условие именно так if (up), без явного присвоения up`у нуля или единицы? Потому что Верилог делали пацаны кодившие на Си (мир ему). Поэтому можно прмяо взять булево значние от сигнала (как от переменной в Си). То есть if(0) это false, a If (1), if(42) это true. В VHDL эта фича появилась только в последних ревизиях. В Верилоге очень много таких штук, которые позволяют сократить объем кода и улучшить читаемость. С другой стороны эти "фичи" при невнимательном использовании позволяют оттяпать себе пальцы, от чего VHDL защищен. Код с доски переписывать не стоит. Используй его только как ориентир, чтобы понять что он хочет. Если не понимаешь, как что то делать, найди рабочий пример, выполни его и потом начинай понемногу модернизировать его в ту сторону, куда тебе надо. Это поможет избежать ситуации "ничего непонятно и ничего не работает". Конечный автомат на Верлиог http://www.altera.com/support/examples/ver...ver_statem.html Quote Share this post Link to post Share on other sites More sharing options...
Михей91 0 December 1, 2012 Posted December 1, 2012 (edited) · Report post Такой вопрос, как принудительно задать задержку на выполнения RST или UP? По данной ссылке http://we.easyelectronics.ru/plis/testbenc...-novichkov.html задержка для RST задается с помощью события, но я не хочу городить такой же огород событий и для UP. Нельзя ли задать задержку более емко и компактно? Разобрался: #30 up = 1; просто смутило то, что когда также описывал задержку для начала RST во временной диаграмме начало RST становилось красным... Но появился еще один вопрос: Разве у нас должен происходить счет, когда RST еще не запущен, ведь он является своего рода кнопкой пуска!? Как это исправить? mur.v `timescale 1ns / 1ps module mur ( input wire clk, input wire rst, input wire up, output reg [3:0] state, output reg [3:0] seq ); // Автомат Мура на 16 состояний // Объявление регистра состояний reg [3:0] reg_state; // Объявление состояний localparam S0 = 4'h0, S1 = 4'h1, S2 = 4'h2, S3 = 4'h3, S4 = 4'h4, S5 = 4'h5, S6 = 4'h6, S7 = 4'h7, S8 = 4'h8, S9 = 4'h9, SA = 4'hA, SB = 4'hB, SC = 4'hC, SD = 4'hD, SE = 4'hE, SF = 4'hF; // Объявление последовательности состояний localparam STATE_0 = 4'h0, STATE_1 = 4'h1, STATE_2 = 4'h2, STATE_3 = 4'h3, STATE_4 = 4'h4, STATE_5 = 4'h5, STATE_6 = 4'h6, STATE_7 = 4'h7, STATE_8 = 4'h8, STATE_9 = 4'h9, STATE_A = 4'hA, STATE_B = 4'hB, STATE_C = 4'hC, STATE_D = 4'hD, STATE_E = 4'hE, STATE_F = 4'hF; // Объявление выходных значений по последовательности состояний согласно варианту localparam SEQ_0 = 4'hF, SEQ_1 = 4'h8, SEQ_2 = 4'h7, SEQ_3 = 4'h0, SEQ_4 = 4'h5, SEQ_5 = 4'h2, SEQ_6 = 4'hC, SEQ_7 = 4'hB, SEQ_8 = 4'h4, SEQ_9 = 4'h3, SEQ_A = 4'hE, SEQ_B = 4'h9, SEQ_C = 4'h6, SEQ_D = 4'h1, SEQ_E = 4'hD, SEQ_F = 4'hA; // SEQ зависит только от одного конкретного состояния always @* begin case (reg_state) S0: begin state = STATE_0; seq = SEQ_0; end S1: begin state = STATE_1; seq = SEQ_1; end S2: begin state = STATE_2; seq = SEQ_2; end S3: begin state = STATE_3; seq = SEQ_3; end S4: begin state = STATE_4; seq = SEQ_4; end S5: begin state = STATE_5; seq = SEQ_5; end S6: begin state = STATE_6; seq = SEQ_6; end S7: begin state = STATE_7; seq = SEQ_7; end S8: begin state = STATE_8; seq = SEQ_8; end S9: begin state = STATE_9; seq = SEQ_9; end SA: begin state = STATE_A; seq = SEQ_A; end SB: begin state = STATE_B; seq = SEQ_B; end SC: begin state = STATE_C; seq = SEQ_C; end SD: begin state = STATE_D; seq = SEQ_D; end SE: begin state = STATE_E; seq = SEQ_E; end SF: begin state = STATE_F; seq = SEQ_F; end default: begin state = STATE_0; seq = SEQ_0; end endcase end // Определение следующего состояния always @ (posedge clk, posedge rst) begin if (rst) reg_state <= S0; else case (reg_state) S0: if (up) reg_state <= S1; else reg_state <= SF; S1: if (up) reg_state <= S2; else reg_state <= S0; S2: if (up) reg_state <= S3; else reg_state <= S1; S3: if (up) reg_state <= S4; else reg_state <= S2; S4: if (up) reg_state <= S5; else reg_state <= S3; S5: if (up) reg_state <= S6; else reg_state <= S4; S6: if (up) reg_state <= S7; else reg_state <= S5; S7: if (up) reg_state <= S8; else reg_state <= S6; S8: if (up) reg_state <= S9; else reg_state <= S7; S9: if (up) reg_state <= SA; else reg_state <= S8; SA: if (up) reg_state <= SB; else reg_state <= S9; SB: if (up) reg_state <= SC; else reg_state <= SA; SC: if (up) reg_state <= SD; else reg_state <= SB; SD: if (up) reg_state <= SE; else reg_state <= SC; SE: if (up) reg_state <= SF; else reg_state <= SD; SF: if (up) reg_state <= S0; else reg_state <= SE; default: reg_state <= S0; endcase end endmodule // mur mur_tb.v `timescale 1ns / 1ps module mur_tb; // Inputs reg clk; reg rst; reg up; // Outputs wire [3:0] state; wire [3:0] seq; // Instantiate the Unit Under Test (UUT) mur uut ( .clk(clk), .rst(rst), .up(up), .state(state), .seq(seq) ); initial begin // Initialize Inputs clk = 0; rst = 0; up = 0; // Wait 20 ns for global reset to finish #20; end // Cоздание CLK always #5 clk = ! clk; // Cоздание RST // Объявление событий event rst_trigger; //вызывается, когда нам необходимо выполнить RST event rst_done_trigger; //сообщает что RST выполнен // Блок формирования RST initial begin forever begin //бесконечный цикл @ (rst_trigger); //ждем события rst_trigger @ (negedge clk); //ждем negedge CLK rst = 1; //сброс @ (negedge clk); rst = 0; -> rst_done_trigger; //сигналим что RST выполнен end end // Ход симуляции initial begin #20 -> rst_trigger; //выполнить RST с задержкой 20нс @ (rst_done_trigger); //ждем сигнал о завершении RST @ (negedge clk); #10 up = 1; repeat (10) begin //цикл на 10 повторений @ (negedge clk); //ждем negedge CLK end up = 0; end endmodule RST включается после того, как CLK переходит из логической 1 в логический 0 (negende), но когда я задаю задержку для RST в 20нс, то на временной диаграмме, в самом начале пока CLK не упал счет отсутствует, что верно, а когда срабатывает условие negende и начинается задержка, то счет начинается, получается что он не видит эту задержку и не реагирует на нее? Хотя задержка UP на счет не повлияла, он все правильно считает... Edited December 1, 2012 by Михей91 Quote Share this post Link to post Share on other sites More sharing options...
Muscat 0 December 1, 2012 Posted December 1, 2012 · Report post >>Разве у нас должен происходить счет, когда RST еще не запущен, ведь он является своего рода кнопкой пуска!? Читай код, там все написано. RST является сигналом сброса, а не пуска. У тебя есть процесс, который сидит в always. Он выполняется либо по фронту клока либо по фронту резета. По клоку он выполняет счет, по резету сброс. Это не я так решил, у тебя так написано. В отсутствии резета он идет по ветке if(rst=1) else и там дальше встречает case и у тебя и идет счет. Почему он не должен идти в case, пока нет резета? Нет причин не идти в case. Если хочешь, чтобы резет был пуском, то добавь некое состояние wait, в котором автомат будет находится по умолчанию и ничего не делать, пока не придет сигнал запуска. Рекомендую все таки вдумчиво выполнить пример с изи-элекроник, осмыслить код, понять что это код делает, помоделировать его и делать свое. Никакого огорода там нет. Quote Share this post Link to post Share on other sites More sharing options...
Михей91 0 December 1, 2012 Posted December 1, 2012 (edited) · Report post Muscat, http://we.easyelectronics.ru/uploads/image...1/24/56a8b3.png ну тут то count не идет пока RST не включится впервые... Edited December 1, 2012 by Михей91 Quote Share this post Link to post Share on other sites More sharing options...
Muscat 0 December 1, 2012 Posted December 1, 2012 · Report post if (reset == 1'b1) begin count <= 0; end else if ( enable == 1'b1) begin count <= count + 1; end 1) Красное, это состояние Х. Физически его не существует, но это удобно при симуляции для ловли багов. Если ты прибавляешь к Х что нибудь, получишь все равно Х. Поэтому вначале долго идет Х. пока ничего не сброшено. 2) Затем приходит резет и сбрасывает счетчик в 0. И стоит в нуле. Недолго, всего 1 такт. 3) На следующем такте резета уже нет, но становится активен сигнал enable. А if enable=1 то клацаем счетчик. Убери енабле и счетчик так и будет стоять в 0. Quote Share this post Link to post Share on other sites More sharing options...
Михей91 0 December 1, 2012 Posted December 1, 2012 · Report post Muscat, спасибо, с автоматом мура покончено, разобрал все что можно, на временной диаграмме все показал. Если кому нужен проект, могу скинуть. Перехожу к реверсивному счетчику... Quote Share this post Link to post Share on other sites More sharing options...
Михей91 0 December 2, 2012 Posted December 2, 2012 · Report post Насчет CL-1 и CL+1, не понял как построить их на XOR3, когда нам нужны два выхода СО и О, СО пойдет на CI выше стоящего, тогда куда пойдет СО самого верхнего? На вход А мы подаем Q (текущее состояние), а В мы должны подобрать так, чтобы реализовывалась функция сложения или вычитания, вот например когда на входы A устройства DEC мы подаем 0000 то чтобы происходил вычет, на В мы должны подать 1111, и на выходе О получаем 1111, что верно из 0 в F, а для INC B = 1110. Но стоит лишь поменять значение Q при таких же В, так на выходе получается уже не то что надо... Мультиплексоры вроде нарисовал... Регистры на FDP, FDC. Зачем мне нужен у FDP вход PRE, что с ним делать... И до сих пор не могу понять сколько мне нужно регистров? 16 штук от 0 до F или же 4 штуки что соответствует 4 разрядам числа... Буфер BUFE. Данный элемент я тоже не нашел, использовать BUFGCE? Но там Clock enable input обозначен как СЕ, мне просто на него маркер поставить со своим обозначение, т.е. OE и ничего страшного? Нарисовал на одном листе мультиплексоры, на выход установил маркер Q_NXT, на другом листе нарисовал регистр, и на вход регистра, согласно схеме, нужно подать Q_NXT с мультиплексора, ставлю маркер, пишу такое же имя, а он мне выдает ошибку мол данное имя уже занято, сделайте другое... вот не понимаю, как тогда мне связать элементы на разных листах? revers_sch.sch Quote Share this post Link to post Share on other sites More sharing options...
Михей91 0 December 3, 2012 Posted December 3, 2012 (edited) · Report post Продвинулся дальше. Выкладываю для критики: revers_sch.sch 1 лист. Так и не понял как быть со значениями B у ADSU4, в мануалы и лампочки не пинайте я там все посмотрел. 3 лист. У FDC таблица логики такая: CLR|D|C|Q 1|X|X|0 0|D|?|D а у FDP такая: PRE|C|D|Q 1|X|X|1 0|?|D|D По факту отличия идут когда CLR и PRE принимают состояние логической единицы, правильно что я поставил инвентор перед PRE, чтобы получать одинаковые выходные значения? 4 лист. На третьем листе мы получили выходы Q[0...3] как мне теперь их объединить в одно целое чтобы подать все на один элемент тристабильного буфера? P.S. наверное я всех достал, приношу свои извинения, ну еще немножко осталось, истина близка) Edited December 3, 2012 by Михей91 Quote Share this post Link to post Share on other sites More sharing options...
Muscat 0 December 4, 2012 Posted December 4, 2012 · Report post Нет, без RTFM к сожалению не получится. Надо все таки read этот FM. >>1)1 лист. Так и не понял как быть со значениями B у ADSU4, в мануалы и лампочки не пинайте я там все посмотрел. ABDUS4 это полный сумматор. На один порт ты подал сигнал Q, молодец. Теперь подумай с чем ты его складываешь и что надо подать на порт B. И зачем тебе 2 сумматора. FDP и FDC это триггеры со сбросом (порт CLR) и с предустановкой в 1 (порт PRE). По получению '1' в этот порт (вроде вход не инверсный) они выполнят соответствующие операции (сброс или предустановка). Инвертор приведет к тому, что у тебя FDC триггеры будут сбрасываться по одному уровню RST, а FDP по другому (ты же инвертор поставил). Подумай, этого ли ты хотел. И зачем 2 разных типа триггеров. >> как мне теперь их объединить в одно целое чтобы подать все на один элемент тристабильного буфера? Один элемент буфера имеет 1 вход. 3 входа в один не впихнуть. Не знаю, как это делается схемотехнически, но думаю, что тебе нужно либо найди буфер, у которого вход будет шиной, либо поставить 4 отдельных буфера, а потом выходы их завести на общую шину. Quote Share this post Link to post Share on other sites More sharing options...