Jump to content

    

sazh

Свой
  • Posts

    2,418
  • Joined

  • Last visited

Everything posted by sazh


  1. Можно найти документ, что без ресета триггеру не жить. По мне, так этим надо пользоваться аккуратно. Если только синтезатор поддерживает начальную инициализацию регистра. И это обычно прописывается в документации. Если FPGA (xilinx, altera) на базе статической ячейки памяти. Так и внутренний сброс по включению питания можно организовать. Тогда ваша времянка моделирования будет соответствовать реальной. А если структура флешь. Не будет соответствия. так что состояние 'x - это благо.
  2. Вы сами выложили проект на 6 бит данных без бита паритета (Получается - это не Ваш проект). Я подправил под 8 с битом паритета. Тестбенч тоже самый простой (Но требуется минимальный набор знаний). Чтобы переключать скорость, нужно ввести признак переключения (вход), по которому можно будет подставлять нужное значение Divider (породить мультиплексор). Смысла в этом нет, ибо не понятно, кто этим входом будет управлять. Да и передатчику откуда будет известно об изменении скорости на прием. Без преподавателя такой проект с нуля (без знаний в схемотехнике ( поэтому большинство предпочитает автоматом состояний отделаться) Вам сознательно не потянуть.
  3. Обычно рекомендации дают для разрабатываемой с нуля платы. Сами пины в схеме подключаете в соответствии с со своим проектом FPGA. Тогда для обеспечения большей стойкости к ESD на неиспользуемые пины например у Альтеры можно использовать опцию As output driving ground. Но вы используете отладочную плату и если Ваш проект окучивает только часть пинов отладочной платы, а остальные физически на плате входы, выходы, в Вашем проекте неиспользованные пины по идее должны иметь опцию типа As input tri-stated. А вообще когда в поверке источник питания был последний раз. Может выбросы по питанию.
  4. Конечно, это не работает, описание оставляет желать лучшего, но функционально все правильно. Что удивительно, вы попытались реализовать UART в стиле UART Электроника 60 (когда то была настольным компьтером). Минимум ресурсов. Остальное - дело наживное. Я влоб подправил. Чтоб работало. Но это, функционально - Ваше. Так что не хуже того, что сейчас в учебниках ваяют. uart.zip
  5. Сомнение гложет. У него только на реализации констант за пределы мелкой CPLD можно вылететь. А что это такое - генератор на аккумуляторе фазы в данном случае?
  6. Начните со своего проекта. Уверяю, у Вас получиться лучше, чем у Тарасова.
  7. Вы назвали его полным сумматором. Проект без расширения разрядной сетки. Не может он складывать и вычитать прекрасно во всем диапазоне входных кодов. Хоть числа со знаком, хоть числа без знака. Ему не хватает выходов переноса и переполнения. Только при расширении разрядной сетки можно говорить об правильных кодах как числа без знака unsigned, со знаком signed. Непонятно, чем Вам не нравиться a-b, a+b. Кстати прекрасную Вам книгу порекомендовали. Я полный сумматор себе так представил. add_sub.v
  8. Все должно работать. 1 создаете *.bsf символ из *.v верхнего уровня. 2 в проекте схематик создает папку project с этим символом, вытаскиваем из нее этот символ в схематик. 3. все множество файлов *.v прописываем в проекте assignments setting files. В RTL просмотрщике смотрим все вложения. В схематике виден только файл верхнего уровня. Нет надобности класть созданный символ в библиотеку.
  9. Так вроде бы в стандарте 2005 уже давно есть встроенная $clog2. Что касается QREG = DATA, тоже не есть хорошо. Что касается проекта uart, то вряд ли кто сделает изящнее, чем это исполнено в ДВК-2. Мне просто стало интересно. зачем Вам мах плюс и графический редактор?
  10. Не надо ничего конвертировать. Если мах+ поддерживает верилог 1999, он должен сгенерировать нетлист для функционального моделирования и дать возможность создать файл временной диаграммы. Дальше моделируете. Я так и не понял, есть ли у Вас проект в графическом редакторе, для которого Вы ищите почему то мах+ именно 9ой версии. Если графический проект есть, то можно забыть о мах+. Последний квартус, который поддерживает семейство флекс 10К - это 9.0 sp2. Можно перетащить в него графический проект и точно также моделировать проекты, независимо от того как они описаны. у него есть встроенное моделирование. Но если переходить на язык описание аппаратуры, желательно пользоваться сторонними пакетами для моделирования. Совместно с квартусом идет пакет Альтера моделсим. Написав тестбенч, можно упаковать его в квартусе в проект и запустить из квартуса моделирование в моделсиме и посмотреть результат. Но переходя на полное текстовое описание как проекта так и описание для него входных возмущений, Вы становитесь независимы от среды проектирования. `timescale 1 ns / 1 ps module dec12_tb; reg S = 1'b1; reg X = 1'b1; wire A0; wire A1; initial begin #10 {S, X} = {1'b0, 1'b1}; #50 #5 $display ("End"); $stop; end dec12 dec12_inst ( .S (S), .X (X), .A0 (A0), .A1 (A1) ); endmodule
  11. Не сможете Вы причесать проект, созданный в графическом редакторе разработчиками прошлого века. Для этого надо мыслить категориями 133 серии. Более того, даже если перенести графику с мах+ на какой нибудь квартус, работать этот проект полно функционально скорее всего не будет. Потому что эти разработки в большинстве своем не соответствуют "золотым" правилам работы с проектами плис, а соответствуют "золотым" правилам работы на "рассыпухе", проверенные на морозе и тепле. Поэтому и хранят раритетные проекты совместно с пакетом, в котором они разрабатывались. И корректируются, если надо, в этой среде проектирования. Перевести в лоб графику на язык описания аппаратуры - пустая затея. Надо все переписывать, не глядя в графику, только опираясь на ТЗ. А совпадение проверить просто. Моделированием в мах+ и моделированием в моделсиме. Времянки (функционально) совпадут. Единственная проблема при переходе на язык описания аппаратуры, которая может возникнуть, которую Вы не видите, это если контрольная сумма *.pof файла старого проекта прописана где нибудь в КД.
  12. Чтоб к смыслу привязаться, имеет значение, какое входное напряжение подается на АЦП, которое не имеет понятия о числах со знаком или без знака. На выходе его по простому - код. Например входной размах АЦП от 0В до 2В. Диапазон 2В. На выходе диапазон кодов от 0000_0000 до 1111_1111. Далее все по ходу пьесы на сумматор, который не имеет понятия о числах со знаком или без знака. Если взять какой нибудь базовый примитив сумматора, то можно заметить что разрядная сетка как по входу, так и по выходу одна и та же, но есть выход переноса. В реальной жизни перенос не используют, сразу расширяют разрядную сетку сумматора как по входу (добавляют в старший разряд 0 к значению кода на выходе АЦП), так и по выходу. В результате во всем диапазоне кодов с выхода АЦП что при сложении кодов, что при вычитании кодов получаете правильный код, называете его число без знака. Дальше как то обрабатываете этот код (если надо поработать с разрядной сеткой). Например входной размах от -1В до +1 В. Диапазон 2В. Этот размах приводят например к входному размаху АЦП (например от 0В до 2В, современные АЦП обычно запитываются от положительного напряжения). На выходе диапазон кодов от 0000_0000 до 1111_1111. Но Вам говорят, что -1В хочу видеть как код 1000_0000, а +1В как код 0111_1111. Напрашиваются числа со знаком. Поэтому диапазон кодов на выходе АЦП от 0000_0000 по 1111_1111 преобразуют в диапазон кодов от 1000_0000 по 0111_1111. В базовом примитиве сумматора, который не имеет понятия о числах со знаком или без знака задействуют выход переполнения. В реальной жизни расширяют разрядную сетку, (по входу размножают уже старший бит кодов от 1000_0000 по 0111_1111. В результате во всем диапазоне кодов с выхода АЦП что при сложении кодов, что при вычитании кодов получаете правильный код, называете его число со знаком. Дальше как то обрабатываете этот код (если надо поработать с разрядной сеткой). Игра ума. Как то так.
  13. Причем тут Си. Пошлите его по углу и по азимуту. Вам предложили инженерный подход. Без всяких калькуляторов. На базе полинома сваять сдвигающий регистр с нужными отводами по xor и отдать на откуп синтезатору байтовую реализацию входных данных. При этом ваш crc16 проект должен удовлетворять как передатчик (налету прогонять массив данных и подставлять в конце массива два байта crc), так и приемник (налету прогонять массив данных с двумя байтами crc, получая сигнатуру (которая известна и всегда одна и та же для конкретной реализации полинома). При этом после вычислений crc16 регистр должен устанавливаться за два такта в состояние ffff, чтоб не дергать его входным сигналом инициализации). //////////////////////////////////////////////////////////////////////////////////////// //G(x) = x16 + x15 + x2 + 1 //////////////////////////////////////////////////////////////////////////////////////// // Module Name = crc_16_8_usb // CRC Width = 16 // Data Width = 8 // CRC Init = ffff // RefIn = true // RefOut = true // Polynomial = 8005 // Check = B4C8 (8'h31, 8'h32....8'h39) // Check with magic world = B001 module crc_16_8_usb ( input [7:0] ibyte, input calc, input init, input clk, output [15:0] crc_rg, output [7:0] crc_check_rg, output [15:0] crc_check16 ); reg [15:0] crc_reg = 16'hffff; reg [7:0] crc_check_reg = 8'hff; wire [15:0] next_crc; ////////////////////////////////////////////////////////////////////////////// // CRC XOR equations ////////////////////////////////////////////////////////////////////////////// function [15:0] crc_16x1 (input [15:0] crc, input d); reg msb; begin msb = crc[15]; crc_16x1 = crc << 1; crc_16x1[0] = d ^ msb; crc_16x1[2] = d ^ msb ^ crc[1]; crc_16x1[15] = d ^ msb ^ crc[14]; end endfunction function [15:0] crc_16_8 (input [15:0] crc, input [7:0] data); integer i; begin crc_16_8 = crc; for (i = 0; i < 8; i= i + 1) // RefIn = true begin crc_16_8 = crc_16x1(crc_16_8, data); end end endfunction /////////////////////////////////////////////////////////////////////////////////// assign next_crc = crc_16_8(crc_reg, ibyte); always @ (posedge clk) begin if (init) begin crc_reg <= 16'hffff; crc_check_reg <= 8'hff; end else if (calc) begin crc_reg <= crc_16_8(crc_reg, ibyte); crc_check_reg <= ~{next_crc[8], next_crc[9], next_crc[10], next_crc[11], // RefOut = true next_crc[12], next_crc[13], next_crc[14], next_crc[15]}; end else begin crc_reg <= {crc_reg[7:0], 8'hff}; crc_check_reg <= ~{crc_reg[0], crc_reg[1], crc_reg[2], crc_reg[3], // RefOut = true crc_reg[4], crc_reg[5], crc_reg[6], crc_reg[7]}; end end assign crc_check_rg = crc_check_reg; ////////////////////////// genvar i; generate for (i = 0; i < 16; i = i + 1) begin : block assign crc_check16 = ~crc_reg[15-i]; // RefOut = true assign crc_rg = crc_reg[15-i]; end endgenerate /////////////////////// endmodule `timescale 1 ns / 1 ps module crc_16_8_usb_tb; parameter halfperiod_100 = 5.0; // 100 MHz reg [7:0] ibyte = 8'h00; reg calc = 1'b0; reg init = 1'b0; reg clk; wire [15:0] crc_rg; wire [7:0] crc_check_rg; wire [15:0] crc_check16; initial begin : clock_generator_100 clk = 1'b0; forever #(halfperiod_100) clk = ~clk; end initial begin repeat (4) @(posedge clk); init = 1'b1; repeat (4) @(posedge clk); init = 1'b0; repeat (4) @(posedge clk); {ibyte, calc} = {8'h31, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h32, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h33, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h34, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h35, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h36, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h37, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h38, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h39, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h00, 1'b0}; repeat (6) @(posedge clk);// Check : B4C8 {ibyte, calc} = {8'h31, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h32, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h33, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h34, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h35, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h36, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h37, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h38, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h39, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'hc8, 1'b1}; repeat (1) @(posedge clk);// Check : B4C8 {ibyte, calc} = {8'hb4, 1'b1}; repeat (1) @(posedge clk);// {ibyte, calc} = {8'h00, 1'b0}; repeat (6) @(posedge clk);// Check : 4FFE //magic world : B001 {ibyte, calc} = {8'h31, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h32, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h33, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h34, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h35, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h36, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h37, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h38, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h39, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'hc8, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'hb4, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'hfe, 1'b1}; repeat (1) @(posedge clk);// Check : 4FFE {ibyte, calc} = {8'h4f, 1'b1}; repeat (1) @(posedge clk);// {ibyte, calc} = {8'h00, 1'b0}; repeat (6) @(posedge clk); // magic world : B001 #5 $display ("End"); $stop; end crc_16_8_usb crc_16_8_usb_inst ( .ibyte (ibyte), .calc (calc), .init (init), .clk (clk), .crc_rg (crc_rg), .crc_check_rg (crc_check_rg), .crc_check16 (crc_check16) ); endmodule
  14. Можно конечный вариант посмотреть. С тестбенчем на посылку c 8'h31 по 8'h39. ( не силен я в VHDL)
  15. А каком алгоритме идет речь? Чтоб всем понятно было. Например: пример спецификации популярного варианта алгоритма "CRC 16" CRC16 стандартный: 1-1000-0000-0000-0101 Name : "CRC 16" Width : 16 Poly : 8005 x^16 + x^15 + x^2 + 1 Init : 0000 RefIn : True RefOut : True XorOut : 0000 Check : BB3D ASCII строки "123456789" (шестнадцатеричные значение "31_32_… 39").
  16. Это стиль проектирования конца 80х, на микросхемах средней интеграции, потом перенос на плис в схемном редакторе. Короче, я хотел сказать, что работа по обеим фронтам в ПЛИС не есть хорошо. Тем паче, что вопрошающий все это промоделировал, я сделал вывод, что может реально по частотам что то не так. Что касается Альтера языка, полностью с Вами согласен. Не согласен про изучение за час, ибо у него нет возможности описать фронт клока и он поэтому опирается на базовые примитивы. Ближайшая альтернатива ему конечно Верилог.
  17. 20 лет прошло. И все равно - кошечка. By Mike Stein, Paradigm Works module toggle_hard_sync ( input in_flag, in_clk, sys_clk, output sys_flag ); reg toggle = 1'b0; reg [2:0] hard_sync_rg = 3'd0; always @(posedge in_clk) begin if (in_flag) toggle <= ~toggle; end always @(posedge sys_clk) begin hard_sync_rg <= {hard_sync_rg[1:0], toggle}; end assign sys_flag = hard_sync_rg[2] ^ hard_sync_rg[1]; endmodule
  18. Вы привели графический вариант, который отличается от вашего проекта rg_ch. А функционально Ваш проект - это д триггер, реализованный на д триггере со входом разрешения и xor в цепи обратной связи. Синтезатор его должен в д триггер превратить. И где тут борьба с метастабильностью. Добавьте еще триггер, будет как в старые добрые времена. Кстати хочу по VHDL проехаться. --signal tg_s : std_logic := '0'; --signal one_tic : std_logic := '0'; Давать указание симулятору - выход логики в ноль установить ? Он конечно проигнорировал, но ему по барабану, сигнал и сигнал. У меня получилось так. Разницы не увидел. module rg_ch ( input clk, change_a, change_b, output [1:0] rg_oa, rg_ob ); reg tg_sa = 1'b0; reg tg_sb = 1'b1; reg [1:0] rg_dff = 2'b10; wire one_tica = change_a ^ tg_sa, one_ticb = change_b ^ tg_sb; always @(posedge clk) begin if(one_tica) tg_sa <= change_a; if(one_ticb) tg_sb <= change_b; rg_dff <= {change_b, change_a}; end assign rg_oa = {tg_sb, tg_sa}, rg_ob = rg_dff; endmodule
  19. Хотелось бы увидеть картинку для моп структуры. Ибо ттл структура для плис не актуальна. Помниться на 133 серии 5 вольтовой ттл логике на висячем входе был уровень 1.3 В и уверенно воспринимался как лог.1
  20. Может статься, эти примитивы только для схематика предназначены. Попробуйте примитив BUFG BUFG_inst ( .O(O), // Clock buffer output .I(I) // Clock buffer input втянуть. Такие примитивы должны подхватываться без всяких путей. Я могу понять про 5титысячник. Я не могу понять про Foundation. Найдите какой нибудь старенький айс, поддерживающий это семейство. С синтезатором, который в должной мере поддерживает язык. По мне, так надо оставить свои наработки в схематике только для поддержки проектов, которые были сделаны в схематике, дорабатывать только в схематике. А если головным модулем проекта является текст, так и все модули пишите в тексте без опоры на примитивы. Иначе о какой переносимости ваших проектов Вы говорите. module ct_div #( parameter xtal_clk = 33_333_333, baud = 115_200 ) ( input clk, input s_rst_n, output enable_wr ); ///////////////// $clog2 function integer clogb2 (input [31:0] value); begin value = value - 1; for (clogb2 = 0; value > 0; clogb2 = clogb2 + 1) value = value >> 1; end endfunction ///////////////// localparam clk_div = xtal_clk / baud, ct_width = clogb2(clk_div); //ct_width = $clog2(clk_div) reg [ct_width-1:0] ct = {ct_width{1'b0}}; reg enable_wr_rg = 1'b0; always @(posedge clk) begin if (s_rst_n == 1'b0) ct <= {ct_width{1'b0}}; else if (ct == clk_div-1) ct <= {ct_width{1'b0}}; else ct <= ct + 1'b1; enable_wr_rg <= (ct == clk_div-1); end assign enable_wr = enable_wr_rg; endmodule
  21. module ct_cb8ce // verilog 2001 ( input c, input clr, input ce, output out_c ); reg [7:0] counter = 8'd0; always @(posedge c or posedge clr) begin if (clr) counter <= 8'd0; else if (ce) counter <= counter + 1'b1; end assign out_c = counter [7]; endmodule
  22. Никто не собирался уделывать VHDL. Если в описании Вы видите, как это описание ложиться на базовые примитивы того или иного семейства, зачем Вам VHDL, если все можно изящно описать, используя всего два типа reg wire Печалька в другом. Искусству схемотехники уже никто не учит.
  23. Правильно мыслите. Какие пологие фронты, если в линии +-5В, а отсекаются при приеме на уровне +-3В. Покритикую проект. Если позволите. Проект не полностью параметризирован (разрядность счетчиков к параметрам не привязана). Загружать счетчики надо (значением - 1), ибо счетчик крутится от 0 до (2**n) -1 и если вдруг загрузите 2**n, загрузите нули. По мне, так в автомате не хватает еще одного состояния. начинаете со старта. Заканчивать надо на стопе (если там будет 0 - это ошибка кадрирования). Мне понравилась реализация 30 тилетней давности в ДВК3. По перепаду из 1 в 0 добегаем до середины стартового бита, и если добежали, от этой середины просто нарезаем биты , в том числе стоп. За 10, 11 бит просто невозможно уход от середины бита в следующий бит. Простой тестовый пример. Если интересно. mail_out_2021.zip
  24. Плясать надо не от библиотек, а от семейства fpga и его структуры. Как раньше говорили, если семейство на базе статической ячейки памяти, регистровая структура инициализируется нулями, что можно использовать для начальной установки регистров в любое значение. Другое дело что (например Альтера) ранние синтезаторы не позволяли это делать простым присваиванием в теле модуля. А теперь могут. Суть от времени не меняется. `timescale 1 ns / 1 ps `define ena_90 module initial_set #( parameter set = 8'd8 ) ( input clk, input [7:0] data_in, input ena, output [7:0] data_out ); `ifdef ena_90 reg [7:0] dffe_rg = 8'd0; assign data_out = dffe_rg ^ set; always @ (posedge clk) begin if (ena) dffe_rg <= data_in ^ set; end `else reg [7:0] dffe_rg = 8'd8; assign data_out = dffe_rg; always @ (posedge clk) begin if (ena) dffe_rg <= data_in; end `endif endmodule