Search the Community
Showing results for tags 'verilog'.
-
Автомат универсального регистра
SarBon88 posted a topic in Языки проектирования на ПЛИС (FPGA)
Добрый день. Пытаюсь собрать автомат универсального сдвигового регистра на Verilog. Получился вот такой код. Iverilog синтезирует и тестбенч работает корректно, но Quartus ругается на использование переменной Q в двух блоках always. Пробовал ввести дополнительную переменную вместо Q во втором блоке always (для последовательного вывода) и присвоить Q в блоке "логика автомата" ее значение, но, к сожалению, таким образом последовательный вывод перестает работать. Также попробовал еще несколько различных вариантов, но результат все тот же. Подскажите, пожалуйста, в какую сторону смотреть. Спасибо. module Universal_Shift_Register #(parameter WIDTH = 5) // параметр позволяет быстро менять разрядность входного числа (clk, res, D, out_state, Load, M, enable); localparam parall_out = 1, logic_shft_left = 2, logic_shft_right = 3, ring_shft_left = 4, ring_shft_right = 5, serial_out = 6; input [WIDTH:0] D; //Входное число input [2:0] Load; //Выбор действия input res, clk; input [WIDTH:0] M; //Количество сдвигаемых разрядов input enable; reg [WIDTH:0] Q; //Результат reg [2:0] state, next_state; output [WIDTH:0] out_state; always @(posedge clk, negedge res) begin if (!res) state <= parall_out; else state <= next_state; end always @(*) //Логика автомата case (state) parall_out: begin if(Load == 1) begin Q = D; //Параллельный вывод next_state = logic_shft_left; end else next_state = parall_out; end logic_shft_left: begin if(Load == 2) begin Q = D << M; //Логический сдвиг влево на М разрадов next_state = logic_shft_right; end else next_state = logic_shft_left; end logic_shft_right: begin if(Load == 3) begin Q = D >> M; //Логический сдвиг вправо на М разрадов next_state = ring_shft_left; end else next_state = logic_shft_right; end ring_shft_left: begin if(Load == 4) begin Q = {D[WIDTH-2:0], D[WIDTH-1]}; // Кольцевой сдвиг влево next_state = ring_shft_right; end else next_state = ring_shft_left; end ring_shft_right: begin if(Load == 5) begin Q = {D[0], D[WIDTH-1:1]}; // Кольцевой сдвиг вправо next_state = serial_out; end else next_state = ring_shft_right; end serial_out: begin if(Load == 6) // Последовательный вывод begin next_state = parall_out; end else next_state = serial_out; end default : next_state = parall_out; endcase reg [WIDTH:0]qQ; // Логика для последовательного вывода always @ (posedge clk, negedge res) // По приходу тактового импульса, в выходную переменную будет записываться [0] разряд входного числа if (!res) Q <= 0; else if (Load == 6 && enable == 1) // enable служит для разрешения записи входного числа в промежуточную REG переменную qQ qQ <= D; else if (Load == 6 && enable == 0) begin Q <= qQ[0]; // Выводим младший разряд входного числа qQ <= {qQ[0], qQ[WIDTH:1]}; // Сдвигаем входное число вправо для передачи следующего разряда end // Логика для реализации передачи результата assign out_state = Q; endmodule -
Ищем ведущего специалиста разработки проектов на ПЛИС. Проекты средней и высокой сложности, по обработке сигналов и с поддержкой скоростных интерфейсов. Работа в команде разработчиков. Заработная плата от 90 000 до 180 000 на руки, определяется по результату собеседования с руководителем. Адрес офиса: г. Санкт-Петербург, Пискарёвский проспект, д. 150, к. 5, «Ручьи». Действует развозка от ст.м. Гражданский пр., Площадь Мужества, Комендантский пр., Пр. Просвещения, Ул. Дыбенко. График работы: 5/2, с 9:00 до 18:00 или с 10:00 до 19:00. Формат: полностью офисный (не дистанционка и не гибрид). Официальное оформление, ДМС после испытательного срока. Требования к кандидатам: ▶ высшее техническое образование; ▶ уверенные знания Verilog; ▶ опыт работы с DSP; ▶ инициативность; ▶ умение работать в команде; ▶ навыки организации работ. Навыки работы с ПО: ▶ Xilinx Vivado; ▶ желательно уметь самостоятельно создавать модели по обработке сигналов на С++, Python, Matlab или других языках. О компании: Специальный технологический центр (сайт компании, хабр). Занимаемся разработкой и производством: ⠀ ▶ систем в сфере информационной безопасности ▶ систем сбора и анализа больших данных с применением методов машинного обучения и искусственного интеллекта ▶ телекоммуникационных систем спутниковой связи ▶ беспилотных летательных аппаратов и квадрокоптеров семейства «Орлан», спутниковых комплексов и систем управления ими ▶ телекоммуникационного оборудования, включая комплексы радиомониторинга, различной военной техники наземного, воздушного и морского базирования Контакты для связи: +7 911 700-09-66 (звонки, Telegram) 8 (812) 244-33-13, доб. 2664 [email protected]
-
Перебираю чужой проект. Подчищаю и "переписываю под себя". Для проверки сравниваю sof файлы "старый" и "новый." Есть вот такая конструкция always @ (posedge clk) begin begin if(Adress_Config == (9'd70 + 9'd256)) begin if(ack_config == 1'b1 && Debug == 1'b1) begin UV_Z <= Data_Config[13:1]; end end end end Я убрал лишне if ((Adress_Config == (9'd70 + 9'd256)) && (ack_config == 1'b1 && Debug == 1'b1)) UV_Z <= Data_Config[13:1]; Сравнение файлов показывает различия. По школьным знаниям могу предположить, что в первом варианте реализуется "приоритетный шифратор", во втором - "дешифратор". На мой взгляд функционировать должно одинаково, но почему генерится другой файл? //----- Ну и чтобы два раза не вставать, встретил два таких оператора вместе if(RM_Rise == 1'b1) Dis_Foto <= 1'b1; if(Res_Dis_Foto == 1'b1) Dis_Foto <= 1'b0; Понятно что Dis_Foto присваивается 1 и 0 одновременно, но при сборке проекта никаких предупреждений не выводиться. Как работает такая конструкция?
-
Здравствуйте! Вопрос по эмуляции вынужденных колебаний. До сих пор читал этот форум наравне с другими источниками инф. по ПЛИС и т.п. Но вот назрел вопрос который показалось уместно задать здесь. Разрабатываю программу на Verilog (т.е. схему для ПЛИС) по управлению генератором переменного тока. Частота и ШИМ будут регулироваться обратной связью по току. Для тестирования нужна функция эмуляции вынужденных колебаний эл.тока. В окончательном варианте будет примерно такое на Verilog: module benchmark(); эмулятор #(.собств_частота(100 тактов)) inst1 ( .clk(clk), .pos // вынуждающее напряжение положительный полупериод 1 бит .neg // отрицательный полупериод 1 бит .ток // это собственно и есть сигнал обратной связи ); инвертор #(мин и макс частоты) uut ( сигналы управления ключами .обратная_связь(ток) ); endmodule Но для начала хотелось бы смоделировать ситуацию на хорошо знакомом мне языке программирования perl. Это поможет уяснить какие параметры нужны. И может пригодиться для генерации табличных функций на Verilog. И так, скрипт просто выводящий синусоиду в стандартный вывод: #!perl use Modern::Perl; my $PI = 3.1415926535; sin $PI/2 == 1.0 or die "assert pi"; my $lvl0 = 40; # середина строки шириной 80 символов my $ampl = 30; my $cur = 0; # начальный ток - 0 my $freq = 50; say 'x' x ($lvl0 + $ampl * sin($PI * 2 / $freq * $_)) for 1..100; как говорится, нет ни чего проще. Это у нас будут типа вынуждающие колебания ) Хотя это совершенно не наш случай. У нас вынуждающие колебания будут прямоугольной формы но это наверное потом. Собственно, мне нужна сама математика. Ну и физика для правильных названий параметров и пр. Для начала затухающие колебания рассмотрим. В принципе объяснение которое я могу понять - нашёл: https://pnu.edu.ru/media/filer_public/2013/04/03/lab59.pdf Но там формула для напряжения а не для тока, если я правильно понял. При затухающих колебаниях... Вот в орфографии perl: q(t) = q0 * e ** (-z * t) * cos(f * t + s0) где q(t) - заряд на конденсаторе в момент времени t q0 - --- в момент времени 0 z - коэффициент затухания = R/2L f - частота колебаний = (f0 ** 2 + z ** 2) ** 0.5 [т.е. корень квадратный] f0 - собственная частота контура = 1 / (L / C) ** 0.5 s0 - начальная фаза (как бы shift) Нужна формула для тока.
-
Есть код сдвигового регистра с асинхронным сбросом и параллельной загрузкой, не могу понять зачем нужны сигналы InS, InP, SHFT, какова их функция?))) можете пожалуйста поподробнее объяснить как они работают в коде
-
Описываю поведение простого UART-передатчика на Verilog в среде Xiling Vivado 2018.2. При присваивании D-триггеру значения с входного порта, он переходит в Z-состояние. Также при попытке присвоить этот сигнал цепи через оператор непрерывного присваивания assign, цепь также принимает высокоимпедансное состояние. В чем может быть причина такого поведения/симуляции, и как это можно исправить? Описание модуля следующее:
- 12 replies
-
- fpga xilinx
- verilog
-
(and 3 more)
Tagged with:
-
Есть желающие позаниматьтся с новичком?
Drakonof posted a topic in Предлагаю работу
Есть разработчики которым не лень позаниматься с новичком?Много уже чего прошел и изучил, но есть достаточное количество дырок в базе. В основном, больше нужно менторство и кодревью + подсказывать куда и как двигаться)По деньгам договоримся. -
Отклик SRRC в QPSK демодуляторе
Zalman_ posted a topic in Алгоритмы ЦОС (DSP)
Добрый день, столкнулся с такой проблемой. Делаю демодулятор QPSK на FPGA Есть QPSK модулятор и соответственно QPSK демодулятор. В модуляторе используется SRRC, что автоматически добавляет такой же SRRC на сторону приемника. В процессе модуляции все происходит корректно и передается на приемник. Замечу, что так как проект сделан на ПЛИС (на данный момент только в коде, то как таковой задержки в чем-либо между модулятором и демодулятором нет). Также отмечу, что SRRC, NCO и частоты идентичны друг другу. По идее, на приемной стороне с выхода SRRC на синфазной и на квадратурной составляющей я должен видеть примерно ту же "картину", что и на выходе SRRC, который стоит в модуляторе. Однако при идентичности параметров и фильтров на приемной стороне SRRC выдает специфичный сигнал, который вроде бы и похож, но тем не менее не соответствует сигналу, получаемому из SRRC в модуляторе. Скрин приложил Скрин из программы ModelSim На скрине входы и выходы SRRC на I и Q в модуляторе и демодуляторе. -
На сайте компании Xilinx размещена для скачивания версия среды разработки для ПЛИС и СнК Vivado под номером 2021.1. Подробнее
-
- vhdl
- fpga xilinx
-
(and 2 more)
Tagged with:
-
Всем привет. Мы проводим стримы по FPGA/ПЛИС тематике на твиче по адресу twitch.tv/fpgasystems Обычно, это среда и суббота в 20:00. Записи прошедших стримов лежат на youtube: youtube.com/c/fpgasystems Ждём Вас на стриме. Анонсы предстоящих эфиров в группе в телеграм @fpgasystems (https://t.me/fpgasystems) и VK и FB
-
FPGA разработчик. Полная занятость (Москва)
MaximBorzov posted a topic in Предлагаю работу
www.kraftway.ru Занимаемся разработкой материнских плат, видеокамер, коммутаторов и т.п. оборудования. Основной долгоиграющий продукт в работе: Микроконтроллер SSD диска. Есть первая рабочая версия. Вторая версия почти готова к отправке на фабрику. Планируем уже разработку третей версии. Там нужно будет принять участие в пересмотре архитектуры продукта. Сейчас под ARM, планируем RISC-V, но это не точно:-) Чем занимаемся: • Разработка конфигураций для FPGA Xilinx Zynq/UltraScale+; • Встраивание сторонних IP-блоков, разработка собственных IP-блоков; • Оптимизация проекта по быстродействию и занимаемым ресурсам; • Отладка интерфейсов взаимодействия FPGA и встроенного процессора ARM • Поддержка наследуемого кода, поиск и исправление в нем ошибок • Добавление в существующие модули новых функциональных возможностей; как пример задачи: разработка контроллера NVME. Пожелания по опыту/навыкам: Знание Verilog; Опыт написания тестбенчей с формированием отчетов; Опыт работы с Xilinx (ISE/Vivado) / Altera (Intel) (Quartus); Опыт работы с ПЛИС со встроенными процессорными ядрами (Xilinx Zynq, Intel Cyclone V SoC, Arria 10 SoC); Команда: 5 разработчиков ПЛИС. Verilog/SystemVerilog + смежные команды (математики, физдизайнеры). 2 верификатора. Redmine/Jira, git. Условия: Склоняемся больше к офисной работе. Но готовы обсудить и удалёнку/полуудалёнку) Место работы: м.Алексеевская, 5 мин.пешком от метро, 15 минут от платформы Рижская. График работы: Пятидневка. 8-часовой рабочий день. Обычно с 10 до 19. По деньгам: ориентир на 150+ т.р. в месяц. Всё в белую. Контакт: Борзов Максим Telegram https://t.me/Maksim_Borzov [email protected]-
- verilog
- systemverilog
-
(and 2 more)
Tagged with:
-
Имеется 4 компонента сгенеренных в цикле genvar i ; // Pad out the input data bus with 0's to 8 bits to avoid errors generate for (i = 0 ; i < (CH_NUMBERS) ; i = i + 1) begin : loop_data_chanel input_channel i_channel( .clk_fabric (clock_x1), .clk_fabric_x2 (clock_x2), .clk_input (clock_x12), .serdes_strobe (serdes_strobe), .tmds_p (LVDS_p[i]), .tmds_n (LVDS_n[i]), .data_out (data_out[11+i*12 : i*12]), .frame (frame) ); end endgenerate Пытаюсь в тестбенче "вывести на картинку" сигнал wire every_other = HG_KG.dvi_decoder.i_channel.i_gearbox.every_other; Modelsim требует указать порядковый номер i_channel. Пробовал квадратные скобки - не пропускает. Почитал документацию на Modelsim. Написано что для VHDL нужно кругные скобки. Попробовал - все равно не подходит.
-
Я получаю на выходе первого модуля "LPT_ASK" 2 регистра и хочу использовать их в другом модуле "assignerer". module LPT_ASK(input wire clk, input wire [7:0]Data, input wire strobe, output reg TX, output reg [3:0]TX_data_bit); reg [7:0]TX_data = 8'b00000000; reg TX_in_progress = 0; reg TX_ended = 1; reg [1:0]strobe_reg; reg flag; always @(posedge strobe) begin TX_data = Data; end always @(posedge clk) begin strobe_reg[0] <= strobe_reg[1]; strobe_reg[1] <= strobe; if ((strobe_reg[1] == 1)&&(strobe_reg[0] == 0)) begin flag = 1; end if ((flag == 1)&&(TX_in_progress == 0)) begin TX_in_progress = 1; TX_data_bit = 4'b0000; TX = 0; end if ((TX_in_progress == 1)&&(TX_data_bit < 4'b1000)) begin TX = TX_data[TX_data_bit]; TX_data_bit = TX_data_bit + 4'b0001; end else begin TX_in_progress = 0; TX = 1; flag = 0; end end endmodule module assignerer ( input wire clk, input wire [7:0]Data, input wire strobe, output wire TX_final, output wire [3:0] TX_final_data_bit ); wire LPT_ASK_to_assignerer; wire LPT_ASK_to_assignerer2; LPT_ASK LPT_ASK1 ( .clk (clk), .Data (Data), .strobe (strobe), .TX (LPT_ASK_to_assignerer), .TX_data_bit (LPT_ASK_to_assignerer2) ); assign TX_final = LPT_ASK_to_assignerer; assign TX_final_data_bit = LPT_ASK_to_assignerer2; endmodule Quartus не выдает ошибок при компиляции, но не похоже, что моя задумка работает. (на диаграмме (wave form diagram ) не видно присвоения) Пытался использовать другую конструкцию. always @(*) TX_final = LPT_ASK_to_assignerer; Но компилятор ругается и выдает ошибку. Буду признателен за любую оказанную помощь
-
Разработка ПЛИС в Санкт-Петербурге (Altera, Verilog)
Spb FPGA posted a topic in Предлагаю работу
Компания ищет для реализации части проекта программиста ПЛИС. Основной проект представляет собой разработку чипа приемника для обработки сигналов (каких сигналов и для чего, расскажем на интервью, разработка мирная, не военное применение). В этом проекте необходимо добавление нового блока обработки сигналов. Есть спецификация блока, описание интерфейсов блока к другим частям чипа, доступны для обсуждения и объяснения дизайнеры и разработчики как железа, так и софта. Задачи представляют собой полный цикл разработки – прочитать спецификацию, обсудить, реализовать, просимулировать с моделью, оттестировать блок, принять участие в тестировании всего проекта. Авторы документации хотя и русскоговрящие, вся документация на английском. Начинать можно уже сейчас. Территориально Санкт-Петербург (удаленная работа будет возможна только в случае если не найдется разработчик в Спб), гибкий график. Если предложение и задачи Вас заинтересовали, отправьте свое резюме на адрес [email protected] Бюджет не ограничен в пределах разумного, резюме с указанием пределов разумного будут рассмотрены с особым вниманием :) -
Подскажите, как запустить на симуляцию несколько модулей verilog в одном waveform в active-hdl?
-
Доброго времени суток. Столкнулся с необходимость описывать ROM на Verilog, под семейство Xilinx. Для этих целей использую $readmemb/$readmemh. Пока длина шины данных меньше или равна 32, то инициализация идет нормально. Как только больше, в симуляторе Active-HDL version 9.3, Verilog 2001, возникает предупреждение. # PLI: $readmemh Too many digits in memory word in file *.txt at line 61437, position 1. Word size is 40 bits [systf:LDM14] В стандарте на Verilog 2001 ограничений на длину слова нет. В документации на Active-HDL, тоже не нашел. Подскажите пожалуйста, можно ли что-нибудь с этим сделать? Всем спасибо.
-
Работа с многомерными массивами.
Tpeck posted a topic in Языки проектирования на ПЛИС (FPGA)
Доброго времени суток. Помогите пожалуйста. Столкнулся со следующей проблемой в Verilog. В качестве базового элемента, допустим, используется массив reg signed [7:0] Data_x [8:0]. Первый вопрос. Правильно ли я понимаю, что каждый раз при при присвоение (i=0; i<9; i=i+1) Data_1<=Data_0(i), необходимо делать цикл по 9 элементам и иначе нельзя? Второй вопрос. Если я захочу передать этот сигнал из компонента на верхний уровень, который написан на VHDL, то мне его надо преобразовать в [71:0] Data_x и передать как std_logic_vectoк(71 downto 0) и в VHDL опять собрать в удобный для работы array? Или можно это сделать как-то проще? Всем спасибо. -
Покрытие кода для FPGA
MaratZuev posted a topic in Среды разработки - обсуждаем САПРы
Добра всем! Поискал в форуме в разных ветках, но сразу не нашёл ответа на такой вопрос: поставлена задача для наших проектов доказать соответствие оных директивам DO-254 и иже с ними. Проекты написаны как на VHDL и Verilog (SV), так и в схематике. Причём ПЛИС Actel и Altera. Вопрос: откуда нам, первый раз столкнувшимся со словами Code Coverage, начать сей нелёгкий и тернистый путь? Всё комментарии, а тем паче, ссылки, книги и прочее, приветствуются. Оптимально Mentor (ModelSim и QuestaSim), но и Aldec пойдёт, если он умеет это лучше. -
Доброго всем пятничного! Либо уже устал к концу недели, либо ещё что, но не могу понять в чём дело: module tb; logic clk; initial begin clk = 0; forever #10ns clk = !clk; end; task process_zone; input logic [7:0] size; output logic process_zone_end; enum {ST_ZONE_IDLE, ST_ZONE, ST_END_ZONE} state_zone; integer i; i = 0; forever @(posedge clk) begin case (state_zone) ST_ZONE_IDLE : state_zone <= ST_ZONE; ST_ZONE : state_zone <= i == size ? ST_END_ZONE : ST_ZONE; ST_END_ZONE : state_zone <= ST_END_ZONE; default : state_zone <= ST_ZONE_IDLE; endcase i = state_zone == ST_ZONE ? i + 1 : 0; process_zone_end = state_zone == ST_END_ZONE; end endtask : process_zone logic state_next_zone; initial #10ns process_zone (8'd5, state_next_zone); endmodule : tb state_next_zone остаётся в третьем состоянии, невзирая на process_zone_end: ЧЯДНТ? Проект на всякий случай также прилагаю. test.zip
-
Компания Syntacore, разработчик микропроцессорного IP, ищет сотрудника на позицию RTL Designer. Обязанности: Разработка и верификация сложных функциональных модулей для ASIC на Verilog/System Verilog. Требования: Опыт разработки и верификации RTL для ASIC от 3 лет; Отличное знание Verilog/System Verilog; Опыт использования RTL симулятора от 3 лет (any vendor); Знакомство с архитектурой современных процессоров, знание современных SoC интерфейсов (ACE, AXI); Уверенный пользователь Linux; Знание английского языка на уровне чтения технической документации и умения вести переписку на технические темы; Опыт работы с системами контроля версий. Мы предлагаем: Высокую оплату труда (по результатам собеседования); Оформление по ТК РФ; Интересную и перспективную работу, возможность быстрого профессионального и карьерного роста; Гибкий рабочий график; ДМС, оплачиваемый отпуск и больничный; Возможность публикаций и поездок на конференции. Контактная информация: [email protected] Дарья Также другие вакансии компании можно посмотреть на сайте https://spb.hh.ru/employer/2132324
-
Разрабатываю CIC фильтр с порядком 7 и больше, децимацией порядка 100 и с сокращением разрядности регистров по методу Хогэнауэра. В расчётах появляются числа с разрядностью 66...80. Пока числа фигурируют в функциях, я могу использовать reg[127:0] для хранения и передачи результатов вычислений. Но при instantiation и generate нужны константы в localparam. А localparam longint param_name = f(x); имеет 64 разряда, что недостаточно. Пишу так, чтобы модель работала в Icarus. Какие предложите способы обойти это?
-
Добра всем! Есть исходный модуль, описанный так: module intm ( input res, input [7:0] di, input wr, input cs, input [3:0] a, output reg [7:0] do, input [7:0] int, output reg [7:0] int_m ); reg [7:0] mode; reg adr; always @ (*) case ({cs,a[3:0]}) 5'b10000 : adr = 1'b1; default : adr = 1'b0; endcase always @ (*) case (adr) 1'b1 : do = mode ; default : do = 8'b0; endcase always @ (posedge res or posedge wr) if (res) mode <= 0; else if (adr) mode <= di ; always @ (*) int_m = (~int) & mode; endmodule И есть его "прилизанная" модификация: module intm ( input res, input [7:0] di, input wr, input cs, input [3:0] a, output [7:0] d_o, input [7:0] intpt, output [7:0] int_m ); reg [7:0] mode; wire adr; assign adr = {cs,a} == 5'b10000 ; assign d_o = adr ? mode : 8'b0 ; always @ (posedge res or posedge wr) if (res) mode <= 8'b0; else if (adr) mode <= di; assign int_m = ~intpt & mode; endmodule Исходный код в RTL выглядит так: в то время как "прилизанный" так: Вопросы: куда делся декодер Decoder0 и какой test bench написать, чтобы доказать или опровергнуть идентичность реализаций? На вс. случай прилагаю сами проекты... new.zip old.zip
-
Как определить уровень
GregoryTMW posted a topic in Языки проектирования на ПЛИС (FPGA)
Здравствуйте, пытаюсь проверить уровень (0 или 1) таким образом: module test( input clk, inout reg in, output reg out,//этот "провод" установил в 1 output reg led ); [email protected](posedge clk) begin if (in == 0) led <= 0; else led <= 1; out <= 1; end endmodule на ножке out устанавливаю 1, и проверяю in, соединяя 2 провода(out и in). При включении светодиод горит постоянно, а при соединении in и out он гаснет. Если код исправить таким образом: if (in == 1) led <= 1; else led <= 0; out <= 1; то светодиод также постоянно горит(хотя провода разомкнуты) и при соединении их светодиод светится ещё ярче, а хотелось бы так: с ножки постоянно подаю 1, а другой ножкой проверяю входящее значение(напряжение) при замыкании этих двух проводов. Если имеется возможность, то пожалуйста покажите как правильно это сделать. -
variable part-select, Verilog
Darky777 posted a topic in Языки проектирования на ПЛИС (FPGA)
Приветствую! Многие кто пишет на SystemVerilog/Verilog знаком с оператором для динамического выбора нужных кусков вектора/переменной/массива_регистров. +: -: Больше часа ломал голову, как применить его в моем случае, может под вечер устал и не соображаю. Вот то, что мне нужен сделать (если бы стандарт верилога поддерживал такую запись для варьируемого индекса) data_o <= {buffer[4+shift_size-1:4],tmp[4:shift_size-1]}; Подскажите, пожалуйста, как описать такую конструкцию? ведь в ней варьируемая ширина вектора, а не фиксированная часть. Поддерживает ли верилог подобные штуки? Вот весь код. Сразу отвечаю, что пока не симулил, т.к. смысла нет (синтаксическая ошибка range must be bounded by constant expressions), и обычно планирую это делать следующим этапом, пока что я уперся в это. Если есть желающие, то прошу оставить обратную связь касательно кода. Буду рад любой аргументированной критике. Под Vivado 2018.2 module frame_aligner ( input clk_i , // Clock input arst_n , // Asynchronous reset active low input sync_i , input [3:0] data_i , output logic [5:0] data_o , output logic valid_o , // duty cycle = 2/3 output logic synced_o ); localparam SYNC_PATT = 12'b111111_000000; localparam SYNC_PATT_MR = ~SYNC_PATT; /*------------------------------------------------------------------------------ -- Functions ------------------------------------------------------------------------------*/ function automatic int unsigned clogb2_pure_f( input [31:0] value ); int unsigned i ; int unsigned temp ; begin temp = 32; for (i=31; i>0; i=i-1) begin if (2**i >= value) begin temp = i; end end return temp ; end endfunction function automatic logic [11:0] dynamic_shift_f ( input [11:0] data_i, input [clogb2_pure_f(12) - 1:0] ss); dynamic_shift_f = data_i; for (int i = 0; i < ss; i++) begin dynamic_shift_f = {dynamic_shift_f[0],dynamic_shift_f[11:1]}; end return dynamic_shift_f; endfunction /*------------------------------------------------------------------------------ -- Signals declaration ------------------------------------------------------------------------------*/ logic sync_ff,sync_fr,sync_cdc; typedef enum logic [1:0] { INIT, FIND_PATTERN, SYNC_MODE_SHIFT,SYNC_MODE_ZERO } fsm_t; fsm_t state, state_next; logic [ 1:0] cnt ; logic [11:0] buffer ; logic strb ; logic [11:0] shifted_data; logic [ 4:0] tmp ; logic match; logic [2:0] shift_size,shift_size_event; /*------------------------------------------------------------------------------ -- Clock Domain crossing ------------------------------------------------------------------------------*/ synchronize_ff #(.FF_CNT(3)) i_synchronize_ff (.clk_i(clk_i), .rstn_i(arst_n), .data_i(sync_i), .data_o(sync_cdc)); always_ff @(posedge clk_i or negedge arst_n) begin : proc_sync_ff if(~arst_n) begin sync_ff <= 0; end else begin sync_ff <= sync_cdc; end end assign sync_fr = !sync_ff && sync_cdc; /*------------------------------------------------------------------------------ -- Functional ------------------------------------------------------------------------------*/ always_ff @(posedge clk_i or negedge arst_n) begin : proc_cnt if(~arst_n) begin cnt <= 0; end else begin cnt <= cnt < 2 ? cnt + 1'b1 : '0; end end assign strb = cnt == 2; always_ff @(posedge clk_i or negedge arst_n) begin : proc_buffer if(~arst_n) begin buffer <= 0; end else begin buffer <= {data_i,buffer[7:4]}; end end always_ff @(posedge clk_i or negedge arst_n) begin : proc_shift_size if(~arst_n) begin shift_size <= 0; end else if ( strb ) begin if( state == FIND_PATTERN ) begin if( !match ) begin shift_size <= shift_size < 5 ? shift_size + 1'b1 : '0 ; end else begin shift_size <= shift_size < 5 ? shift_size + 1'b1 : '0 ; end end end end assign shift_size_event = ( shift_size != 0 ) ? ( 5 ) : ( shift_size - 1 ); always_ff @(posedge clk_i or negedge arst_n) begin : proc_shifted_data if(~arst_n) begin shifted_data <= 0; end else if (strb) begin shifted_data <= dynamic_shift_f(buffer,shift_size); end end assign match = ( shifted_data == SYNC_PATT ) || ( shifted_data == SYNC_PATT ); /*------------------------------------------------------------------------------ -- FSM ------------------------------------------------------------------------------*/ always_ff @(posedge clk_i or negedge arst_n) begin : proc_state if(~arst_n) begin state <= INIT; end else begin state <= state_next; end end always_comb begin : proc_state_next state_next = state; case (state) INIT : state_next = ( sync_fr ) ? ( FIND_PATTERN ): ( state ); FIND_PATTERN : state_next = ( match ) ? ((shift_size_event != 0 ) ? (SYNC_MODE_SHIFT) : (SYNC_MODE_ZERO)): ( state ) ; SYNC_MODE_SHIFT : state_next = state; SYNC_MODE_ZERO : state_next = state; default : state_next = INIT ; endcase end /*------------------------------------------------------------------------------ -- data to output ------------------------------------------------------------------------------*/ always_ff @(posedge clk_i or negedge arst_n) begin : proc_data_o if(~arst_n) begin data_o <= '0; valid_o <= 1'b0; tmp <= '0; end else begin case (state) SYNC_MODE_SHIFT : begin case (cnt) 1 : begin data_o <= {buffer[4+shift_size-1:4],tmp[4:shift_size-1]}; // ВОТ ТУТ! valid_o <= 1'b1; end 2 : begin data_o <= buffer[shift_size +:6]; tmp <= buffer[11:7]; valid_o <= 1'b1; end default : begin data_o <= data_o; valid_o <= 1'b0; end endcase end SYNC_MODE_ZERO : begin case (cnt) 1 : begin data_o <= buffer[7:2]; end 2 : begin data_o <= buffer[5:0]; end default : begin data_o <= data_o; valid_o <= 1'b0; end endcase end default : data_o <= data_o; endcase end end always_ff @(posedge clk_i or negedge arst_n) begin : proc_synced_o if(~arst_n) begin synced_o <= 1'b0; end else if ( match ) begin synced_o <= 1'b1; end end endmodule -
Доброго времени! Прошу совета у сообщества. "Сам я в верилог недавно". Пытаюсь таким образом: `timescale 1 ps / 1 ps module sram_adapter #(parameter gp_SRAM_D_WIDTH = 8, parameter gp_SRAM_A_WIDTH = 12, parameter gp_SRAM_WORD_SIZE = 1<<gp_SRAM_A_WIDTH) ( input [(gp_SRAM_D_WIDTH-1):0] i_d0, input [(gp_SRAM_D_WIDTH-1):0] i_d1, input [(gp_SRAM_A_WIDTH-1):0] i_add0, input[(gp_SRAM_A_WIDTH-1):0] i_add1, input[(gp_SRAM_A_WIDTH-1):0] i_add2, input i_clock, input i_add0bus_sel, input i_add1bus_sel, input i_add2bus_sel, input i_rden0, input i_rden1, input i_wren0, input i_wren1, input i_noe_uc, input i_nwe_uc, input i_ncs_uc, input [(gp_SRAM_A_WIDTH-1):0] i_add_uc, output wire[(gp_SRAM_D_WIDTH-1):0] o_d0, output wire [(gp_SRAM_A_WIDTH-1):0] o_add, inout [(gp_SRAM_D_WIDTH-1):0] io_d_uc, output dbg0, output dbg1, output dbg2 ); reg [(gp_SRAM_A_WIDTH-1):0] r_a; reg[(gp_SRAM_D_WIDTH-1):0] r_d; reg[(gp_SRAM_D_WIDTH-1):0] r_q; assign o_add = r_a; assign o_d0 = r_q; reg [3:0]r_bus_mux_sel, r_we, r_oe; assign dbg0 = (r_oe); assign dbg1 = (r_we); assign dbg2 = |r_bus_mux_sel; reg [gp_SRAM_D_WIDTH:0] sram[(gp_SRAM_WORD_SIZE-1):0]; initial begin r_a = 0; r_q = 0; r_oe = 0; r_we = 0; end // Tri-State Buffer control assign io_d_uc = (r_bus_mux_sel[3] && !i_noe_uc && i_nwe_uc) ? r_q: 8'bz; always @(negedge i_clock) begin r_bus_mux_sel[3] <= !i_ncs_uc; r_bus_mux_sel[0] <= i_add0bus_sel; r_bus_mux_sel[1] <= i_add1bus_sel; r_bus_mux_sel[2] <= i_add2bus_sel; end always @(posedge i_clock) begin if(r_we) sram[r_a] <= r_d; if(r_oe) r_q <= sram[r_a]; end localparam lp_TX1BUF_ADD_OFFSET = 12'd16, lp_RX1BUF_ADD_OFFSET = 12'd96; always @(i_add_uc or i_add0 or i_add1 or i_add2 or r_bus_mux_sel) begin casex (r_bus_mux_sel) 4'd1: r_a = i_add0; 4'd2: r_a = i_add1 + lp_TX1BUF_ADD_OFFSET; 4'd4: r_a = i_add2 + lp_RX1BUF_ADD_OFFSET; 4'b1xxx: r_a = i_add_uc; default: r_a = 12'd4095; endcase end always @(i_d0 or i_d1 or r_bus_mux_sel) begin casex (r_bus_mux_sel) 4'd1: r_d = i_d0; 4'd4: r_d = i_d1; 4'b1xxx: r_d = io_d_uc; default: r_d = 0; endcase end always @(i_wren0 or i_wren1 or i_nwe_uc or r_bus_mux_sel) begin casex (r_bus_mux_sel) 4'd1: r_we = i_wren0; 4'd4: r_we = i_wren1; 4'b1xxx: r_we = !i_nwe_uc; default: r_we = 0; endcase end always @(i_rden0 or i_rden1 or i_noe_uc or r_bus_mux_sel) begin casex (r_bus_mux_sel) 4'd1: r_oe = i_rden0; 4'd2: r_oe = i_rden1; 4'b1xxx: r_oe = (!i_noe_uc && i_nwe_uc); default: r_oe = 0; endcase end endmodule К памяти подключен внешний МК: i_noe_uc, input i_nwe_uc, input i_ncs_uc, i_add_uc, io_d_uc и внутренние "читатели/писатели"(1 писатель/читатель, 1 читатель, 1 писатель). Результат использования такой: - синтезируется ОЗУ, запрошенного объема 4096 байт; - тесты записи/чтения по всему объему со стороны МК проходят успешно; - внутренние "читатели/писатели" читают и пишут успешно; НО, как-будто это две разные ОЗУ. Т.е. если записать МК какие-либо данные в определенный адрес (диапазон адресов), то внутренний читатель вычитывает с этого адреса (адресов) исключительно, то, что туда записывает внутренний писатель. Равно как и МК вычитывает, только то, что сам записал.