Jump to content

    

bmangust

Участник
  • Content Count

    13
  • Joined

  • Last visited

Community Reputation

0 Обычный

About bmangust

  • Birthday 09/02/1989

Информация

  • Город
    Array
  1. спасибо, буду в следующий раз избегать этого :) тогда еще вопрос: можно ли внутри ПЛИС использовать значения "хххх" вместо чисел? Квартус как бы предупреждает и еще выдал вот что: тут имеется в виду то, что при тактировании схемы сигналом с высокой частотой регистры не смогут вовремя переключиться? Или при любой частоте тактирования регистры не будут успевать?
  2. Собственно, в этом коде Quartus выадет ошибку 10028 (а именно, во втором блоке "always @"): // decrement number (ram), recieved from shift_register // and synchronously increment binary counters "units", "tens", "hundreds", "thousands". // then unite them into BCD number. // when ram == 0, send signal (cs_down) to the shift_register to collect new data module converter ( input [11:0] data_in, // data from shift_register ([11:0] sr) input clk, ready, // "ready" signal from the shift_register.v output reg [14:0] disp_BCD, // display memory, binary-coded decimal //([14:12] - thousands, [11:8] - hundreds, [7:4] - tens, [3:0] - units) output reg cs_down // to the shift_register.v ); reg [3:0] units = 4'hx; // units counter reg [3:0] tens = 4'hx; // tens counter reg [3:0] hundreds = 4'hx; // hundreds counter reg [2:0] thousands = 3'hx; // thousands counter reg [11:0] ram; // declare RAM, dercement counter wire units_over = (units [3:0] == 4'h0); wire tens_over = (tens [3:0] == 4'h0) & units_over; wire hundreds_over = (hundreds [3:0] == 4'h0) & tens_over; always @ (negedge clk) if (ready) begin ram <= data_in; // Write data to memory units <= 4'bx; // and clear counters tens <= 4'bx; // 4'bx used to avoid unexpected increments hundreds <= 4'bx; thousands <= 3'bx; end else; always @ (posedge clk) if (ram == 12'b0) cs_down <= 1'b1; else begin ram <= ram - 1'b1; cs_down <= 1'b0; if (units == 4'b1011) units <= 4'b0000; else units <= units + 1'b1; end always @ (posedge units_over) if (tens == 4'b1011) tens <= 4'b0000; else tens <= tens + 1'b1; always @ (posedge tens_over) if (hundreds == 4'b1011) hundreds <= 4'b0000; else hundreds <= hundreds + 1'b1; always @ (posedge hundreds_over) if (thousands == 3'b100) thousands <= 3'b000; else thousands <= thousands + 1'b1; always @ (negedge cs_down) disp_BCD <= {thousands, hundreds, tens, units}; endmodule Что ожидается от схемы:
  3. Советую добавить "posedge" у сигналов IN0 и IN1 в блоке чувствительности, и туда же отправить "posedge RESET". Так вы получите асинхронный сброс. Иначе вы пытаетесь изменять значения счетчика при любом изменении сигналов IN0 и IN1.
  4. Возможно, ошибка в этом: вы запускаете на симуляцию модуль верхнего уровня, при этом не указав все сигналы. Для того, чтобы проверить модули Ser и Deser отдельно, можно создать один файл векторной диаграммы для модуля верхнего уровня, там указать все входы-выходы, и для входов задать воздействия. Модули просимулируются отдельно, т.к. сейчас вы только продекларировали их, но не связали путями внутри верхнего модуля. Еще вариант - сделать верхним модулем один из модулей, скажем Ser, провести его симуляцию, потом так же со вторым.
  5. 2Shtirlits: Алгоритм определенно интересен, правда, разобрался в нем только с посторонней помощью. Проверьте, правильно ли я понял: Счет ведется от 0 до 5000. Для подсчета единиц используется сдвиговый 10-битный регистр, в котором единичка движется от разряда к разряду при уменьшении на 1 12битного сдвигового регистра, где хранятся данные с АЦП. Для хранения значения "единиц" после окончания 12битного регистра будет использоваться 4х битный регистр, в который закладывается номер порядка 10битного регистра, где остановилась единичка. Если 10битный регистр "закончился", то мы добавляем "1" к одному из 4х-битных счетчиков, отвечающему за десятки (пусть будет "А"). И снова прогоняем единичку по 10ибтному регистру. Когда наш 4х битный счетчик "А" покажет значение "1001" при следующем полном проходе 10битного регистра мы обнуляем 4х битный счетчик "А" и добавляем единицу к 4х битному счетчику "В", отвечающему за сотни. Предыдущие 2 пункта повторять, пока счетчики "А" и "В" не покажут значения "1001". Дальше, если 12-битнй регистр все еще не опустел, увеличиваем значение регистра "С" (его можно оставить 3х битным, ибо тысяч будет всего 5. В целях универсальности можно сделать по аналогии с "А" и "В"). При значении регистра "С", равном "101" исходный сдвиговый регистр должен полюбому закончится. Если все так и есть, то его реализация займет 37LE (не так уж и много). Но есть еще нюанс. Это ведь синхронная схема? АЦП придется тактировать сигналом в 4095 раз более медленным, что при частоте ПЛИС 50МГц составит 12кГц (вроде так). Это необходимо, чтобы за один цикл передачи данных ПЛИС успела раскодировать сигнал. 2Alex11: Для реализации двоично-десятичного инкремента на 4 десятичных цифры надо будет заюзать 16-битный счетчик? или отдельно 4 4х-битных счетчика? 2griha-leha: меня смущает вот это присвоение: assign U_dysplay = U_mes + U_mes[11:3] + U_mes[11:4] +U_mes[11:5] +U_mes[11:9]; там же переполнение будет, если U_mes [11:0] = 12'hFFF? Модуль индикации, выдрал из предыдущего проекта, еще не адаптировал под этот. Думаю принцип будет схожий - 4 числа в памяти, динамическая индикация и все такое. В старшем разряде будет гореть десятичная точка: module led_driver (NUM0, NUM1, NUM2, NUM3, clk, LED, AN); input clk; input [3:0]NUM0, NUM1, NUM2, NUM3; output [0:7]LED; //LED segments output [3:0]AN; //LED anodes reg [3:0]AN; reg [0:7]LED; reg [3:0]CODE; reg [1:0]DRV; //check DRV wise if inceace quantity of 7-seg displays (default: 4 disp => DRV[1:0]) always @(posedge clk) begin begin if (DRV==2'b11) DRV <= 2'b00; else DRV <= DRV+1; end //bus DRV drives displays multiplexing case (DRV) 2'b00: CODE <= NUM0; 2'b01: CODE <= NUM1; 2'b10: CODE <= NUM2; 2'b11: CODE <= NUM3; endcase case (DRV) 2'b00: AN <= 4'b0111; 2'b01: AN <= 4'b1110; 2'b10: AN <= 4'b1101; 2'b11: AN <= 4'b1011; endcase //CODE reg keeps one of dights and redirect it to output LED case (CODE) 4'b0000: LED <= 8'b11111100; 4'b0001: LED <= 8'b01100000; 4'b0010: LED <= 8'b11011010; 4'b0011: LED <= 8'b11110010; 4'b0100: LED <= 8'b01100110; 4'b0101: LED <= 8'b10110110; 4'b0110: LED <= 8'b10111110; 4'b0111: LED <= 8'b11100000; 4'b1000: LED <= 8'b11111110; 4'b1001: LED <= 8'b11110110; default: LED <= 8'b00000000; endcase end endmodule
  6. Если выводить содержимое сдвигового регистра, то тогда надо 12 индикаторов, не? Руководитель хотел добиться отображения напряжения в вольтах с точностью до 3й цифры после запятой (диапазон от 0 до 5В). В перспективе еще и динамическое изменение диапазиона %) Индикация динамическая, иначе пришлось бы угробить все выводы на подключение только 4х индикаторов (у меня чип в 44-PLCC корпусе).
  7. 2Shtirlits Ну да, 64 ячейки это мало. У меня блок индикации на 4 7-сегментрых дисплея занимает 18 ячеек, сдвиговый регистр с памятью - 30, остается еще 16. Если хитро извернуться, может и хватит, впритык. В принципе, есть еще MAXII micro kit, в крайнем случае можно его заюзать. Но уже самому интересно, реально или нет сделать это на MAX7k. Преподователь раньше занимался (и сейчас занимается) микроконтроллерами, с ПЛИС не работал. Поэтому у него свои представления о возможностях микросхем. Как - так? :)
  8. Доброго времени суток! Изучаю ПЛИС в институте, научный руководитель поставил задачу сделать вольтметр на основе CPLD MAX7064 и АЦП ads7816. Эта ацп выводит данные с помощью последовательного интерфейса (12 бит). Сдвиговый регистр с памятью и блок индикации я написал. Но для того, чтобы преобразовать двоичный код с ацп в значение напряжения хотел использовать константы, операции возведения в степень и умножения. Оказалось, квартус не воспринимает переменные типа real, а для выполнения умножения или возведения в степень надо воспользоваться мегафункциями, которые недоступны для данного семейства ПЛИС. Как поступить в этом случае - менять алгоритм преобразования (не представляю на какой) или еще что-то? Вот алгоритм преобразования, для справки: parameter LSB = 1.22; begin : multiplection integer i; result = 0; for (i = 0; i < 12; i = i + 1) result = result + (data_in[i]*(2**i)*LSB); end и таблица преобразования из даташита ацп в приложении
  9. evgforum, iosifk спасибо. 2 iosifk: CDC это, я понимаю, clock domain crossing?
  10. Снова я. Проблема с работой схемы решена. Остался только вопрос: как реализовать запуск схемы по фронту сигнала, например SET (чтобы устранить дребезг контактов). У меня получается заставить работать только при нажатой кнопке.
  11. Добрый день. Нужно реализовать следующую схему: есть несколько входов (SET, RST, DATA) и 2 выхода. При нажати SET на один из выходов должен прийти 0 сразу, а на второй - через определенный интервал. Величина интервала задается 4х битным числом DATA. Организовал это через счетчик и if (пробовал через for - не получилось, 0 приходит одновременно). module delay (clk, SET, OUT, RST, DATA, a); input clk, SET, RST; input [3:0] DATA; output [0:1] OUT; output [19:0] a; reg [0:1] OUT; reg [3:0] cnt; reg [19:0] a; always @(posedge clk) begin a[19:0] <= 20'b11111_11111_11111_11111; if (RST) begin OUT[0] <= 1'b1; OUT[1] <= 1'b1; end else if (SET) begin cnt <= cnt + 1'b1; OUT[0] <= 1'b0; case (DATA) 4'h0:if (cnt[0]) OUT[1] <= 1'b0; 4'h1:if (cnt[1]) OUT[1] <= 1'b0; 4'h2:if (cnt[1]&cnt[0]) OUT[1] <= 1'b0; 4'h3:if (cnt[2]) OUT[1] <= 1'b0; 4'h4:if (cnt[2]&cnt[0]) OUT[1] <= 1'b0; 4'h5:if (cnt[2]&cnt[1]) OUT[1] <= 1'b0; 4'h6:if (cnt[2]&cnt[1]&cnt[0]) OUT[1] <= 1'b0; 4'h7:if (cnt[3]) OUT[1] <= 1'b0; 4'h8:if (cnt[3]&cnt[0]) OUT[1] <= 1'b0; 4'h9:if (cnt[3]&cnt[1]) OUT[1] <= 1'b0; 4'hA:if (cnt[3]&cnt[1]&cnt[0]) OUT[1] <= 1'b0; 4'hB:if (cnt[3]&cnt[2]) OUT[1] <= 1'b0; 4'hC:if (cnt[3]&cnt[2]&cnt[0]) OUT[1] <= 1'b0; 4'hD:if (cnt[3]&cnt[2]&cnt[1]) OUT[1] <= 1'b0; 4'hE:if (cnt[3]&cnt[2]&cnt[1]&cnt[0]) OUT[1] <= 1'b0; default : OUT[1] <= 1'b1; endcase end end endmodule Замечание: светодиод на выходе горит, если на выход подается 0, т.к. там стоит усиливающий транзистор, который открывается, если его притянуть на землю. Для этого же на выводы a[19:0] подаются 1 - чтоб не горели лишние светодиоды. Возникли такие вопросы: 1. при симуляции в Waveform Editor'е все работает нормально, при нажатии RST (и далее при его отпускании) на выходы подается 1, при SET == 1 счетчик считает и гасит второй выход через заданный промежуток. При прошивке CPLD единица на выходы подается только при активном RST, если же на RST 0, то на выходах 1. 2. счетчик считает только при SET==1. Как можно сделать так, чтобы при однократном нажатии на SET запускался процесс счета. Или, как вариант, сделать что-то типа триггера Шмидта на входе, чтоб убрать возможные дребезжания кнопок. Тогда как его сделать, через latch? Спасибо