Search the Community
Showing results for tags 'systemverilog'.
-
Здравствуйте. Есть такой код: class driver... task main; automatic int sender_iterator; ... forever begin ... sender_iterator=0; while(sender_iterator<t.transaction_full.size) begin fork automatic int k = sender_iterator; begin $display("---transaction index automatic %d---", k); $display("---transaction index foreach %d---", sender_iterator); send_UDDCP_arr(t.transaction_full[k], UDDCP_inputs[k]); end join_none sender_iterator++; end ... wait fork; ... end endtask endclass Когда происходит первая итерация цикла forever begin, я вижу в консоли: # ---transaction index automatic 10--- # ---transaction index foreach 11--- # ---transaction index automatic 9--- # ---transaction index foreach 11--- # ---transaction index automatic 8--- # ---transaction index foreach 11--- # ---transaction index automatic 7--- # ---transaction index foreach 11--- # ---transaction index automatic 6--- # ---transaction index foreach 11--- # ---transaction index automatic 5--- # ---transaction index foreach 11--- # ---transaction index automatic 4--- # ---transaction index foreach 11--- # ---transaction index automatic 3--- # ---transaction index foreach 11--- # ---transaction index automatic 2--- # ---transaction index foreach 11--- # ---transaction index automatic 1--- # ---transaction index foreach 11--- # ---transaction index automatic 0--- # ---transaction index foreach 11--- Но во второй итерации я вижу: # ---transaction index automatic 21--- # ---transaction index foreach 22--- После этого я обращаюсь к несуществующему элементу, и программа падает. Почему не обнуляется sender_iterator?
-
Собственно, вопрос в заголовке. Мне нужно загрузить данные из всех файлов, содержащих определённую подстроку.
-
Здравствуйте. В пакете есть задача: task wait_one(inout logic c, s); while(1) begin @(posedge c); if(s) break; end endtask Я вызываю её внутри класса таким образом: task automatic send_UDDCP(UDDCP_transaction_full transaction, virtual UDDCP_interface intf); ... wait_one(intf.clk, intf.read_ready); ... endtask Проблема в том, что строчка @(posedge c); никогда не исполняется. Но, если заменить этот код на другой, без вызова задачи, всё работает: task automatic send_UDDCP(UDDCP_transaction_full transaction, virtual UDDCP_interface intf); ... while(1) begin @(posedge intf.clk); if(intf.read_ready) break; end ... endtask Насколько я понимаю, верилог копирует c и s только 1 раз при входе в задачу. Я попробовал другой вариант: task automatic wait_one(ref logic c, s); while(1) begin @(posedge c); if(s) break; end endtask Но, когда я пытаюсь запустить симуляцию, мне говорят, что "Actual argument expression for ref formal 'c' is not an equivalent type." Системверилог не умеет передавать ссылку на поле виртуального интерфейса, или в чём проблема?
-
Есть конструктор: function new (const ref UDDCP_header h, const ref int unsigned d[$], bit v[$], int b, int a); Так он работает: int be, aa; ... be = 100; aa = 250; trans_single = new(h[i],d[i],valids_single,be,aa); А так нет: trans_single = new(h[i],d[i],valids_single,100,250); Моделсим при компиле говорит, что "The expression "100" is illegal for use with ref argument "b"". Почему?
-
Здравствуйте. У меня есть модуль с массивом интерфейсов в портах. Как передать этот массив в тест? Я создал ещё один параметризованный тип интерфейса, где параметр - число исходных интерфейсов. Всё компилится, но, когда я запускаю симуляцию, моделсим пишет, что "illegal assignment to type 'virtual UDDCP_interface_arr' from type 'interface UDDCP_interface_arr #(11)". Видимо, мне надо как-то передать параметр внутрь блока program, чтобы при этом параметр был виден уже в портах. Я попытался это сделать, но так не компилится, выдаёт ошибку из-за того, что рараметр объявлен позже, чем используется: program test(UDDCP_interface UDDCP_rout, UDDCP_interface_arr #(p) UDDCP_inputs, additional_ports add_ports); parameter p=11; ... Можно как-то сделать параметризованные порты у program? Я не нашёл примеров. Или вообще можно не городить огород, а просто как-то передавать массив интерфейсов через программу в объект класса? На всякий случай файлы исходников прикреплю. new.7z
-
Условия для covergroup systemverilog
g700 posted a topic in Языки проектирования на ПЛИС (FPGA)
Всем привет! Помогите, пожалуйста, разобратся с условиями для covergroup. Цель следующая, учитывать значение в coverpoint только когда оно валидно. Вот варианты: covergroup iff_cg @( posedge clk ); value_cp : coverpoint dif.value iff ( dif.valid && dif.flag ) { } endgroup covergroup pos_iff_cg @( posedge clk iff ( dif.valid && dif.flag ) ); value_cp : coverpoint dif.value { } endgroup covergroup smpl_cg; value_cp : coverpoint dif.value {} endgroup smpl_cg _smpl; pos_iff_cg _pos_iff; iff_cg _iff; task cc(); forever begin @( posedge clk ); if( dif.valid && dif.flag ) begin _smpl.sample(); end end endtask Получается так, что pos_iff_cg и smpl_cg дают ожидаемый результат, а в iff_cg не хватает попаданий, но при этом все значениям которые были в тесте есть. Как правильно делать в таких случаях? Скрин: Я думал столбец Coverage для bin -- это кол-во попаданий, или это не так? Тогда как интерпретировать этот столбец? Код в архиве, симулятор Questa. cover_min.zip-
- systemverilog
- covergroup
-
(and 2 more)
Tagged with:
-
Приветствую Возник вот такой вопрос- Есть интерфейс с пучком сигналов которые для удобства определены как структура interface if_TEST #(ID_WH=3) ; typedef struct packed { u1_t [ID_WH-1:0] sig0; u1_t sig1; u7_t sig2; //... } st_TEST_t; st_TEST_t st; bit valid; bit ready; modport in (input st, valid, output ready); modport ou (output st, valid, input ready); endinterface и хочется мне в месте где такой интерфейс применяется получить актуальную ширину структуры в битах. Поскольку реальное значение будет зависит от параметра который меняется при инстанцировании интерфейса. Казалось бы что проще module test (if_TEST.in if_test, ...); localparam ST_WH = $bits(if_test.st); ... module top (...); if_TEST #(4) if_test (); test i_test(.if_test(if_test), ...); ... На что получаю в Modelsim (Intel start edition 2020.1/2020.3) маловразумительную ошибку - ** Error: (vsim-8894) In instance ".../i_test" parameter reference "if_test.st" through interface port "if_test" is not valid when the actual interface in the instance is an arrayed instance element or below a generate construct." Маловразумительную потому что этот интерфейс инстанцирован сам по себе - ни как array, ни из под generate. Самое прикольное что в Qu все синтезируется как надо, а в Modelsim такая вот засада. Вот и ломаю голову как сделать чтобы и в симе и в синтезе получать нужное заначене ширины. Удачи! Rob.
-
Приветствую всех! С SystemVerilog пока особого опыта нет, изучаю понемногу. Тестбенч, все сгенерировано с помощью Clarity ( Lattice Diamond 3.12 ) В топ модуле тестбенча pix2byte_tb.v определенны различные параметры, например num_frames `timescale 1 ps / 1fs `include "dut_defines.v" `include "tb_params.v" `include "vid_timing_gen_driver.v" `include "byte_out_monitor.v" module top(); `include "dut_params.v" parameter num_frames = `NUM_FRAMES; parameter hfront_porch = `HFRONT; parameter hsync_pulse = `HPULSE; parameter hback_porch = `HBACK; parameter vfront_porch = `VFRONT; parameter vsync_pulse = `VPULSE; parameter vback_porch = `VBACK; //`ifndef MISC_ON // parameter init_drive_delay = `INIT_DRIVE_DELAY; //`endif parameter output_width_in_bytes = (DATA_WIDTH*NUM_TX_LANE*TX_GEAR)/128; parameter input_width_in_bits = PIX_WIDTH*NUM_PIX_LANE; parameter input_width_in_bytes = input_width_in_bits[0] ? input_width_in_bits : input_width_in_bits[1] ? input_width_in_bits/2 : input_width_in_bits[2] ? input_width_in_bits/4 : input_width_in_bits/8; parameter multiple_bytes = input_width_in_bytes*output_width_in_bytes; parameter least_common_multiple_bytes = multiple_bytes[0] ? multiple_bytes*4 : multiple_bytes[1] ? multiple_bytes*2 : multiple_bytes; parameter number_of_bytes = (1 + `NUM_BYTES/least_common_multiple_bytes)*least_common_multiple_bytes; parameter total_pix = number_of_bytes*8/PIX_WIDTH; parameter act_pix = total_pix/NUM_PIX_LANE; parameter total_line = `NUM_LINES; parameter pixclk_period = `SIP_PCLK/2; parameter byteclk_period = (pixclk_period*DATA_WIDTH*NUM_TX_LANE*TX_GEAR)/(PIX_WIDTH*NUM_PIX_LANE*16); localparam exp_byte_count = `NUM_FRAMES * `NUM_LINES * number_of_bytes; reg reset_n; reg pix_clk_i = 0; reg byte_clk_i = 0; reg mon_en = 0; reg start_vid = 0; reg byte_log_en = 0; wire rst_n_i = reset_n; wire byte_clk = byte_clk_i; integer line_cnt = 0; integer frame_cnt = 0; integer pixel_cnt = 0; integer testfail_cnt = 0; integer txfr_delay = 100000/byteclk_period; integer wc_delay = number_of_bytes/(GEAR_16+1)*NUM_TX_LANE; reg dvalid_i; wire de_i; wire hsync_i, vsync_i; wire fv_i, lv_i; wire eof; wire [PIX_WIDTH-1:0] pix_data9_i; ..... потом в тексте есть include ............... `ifdef TX_DSI `include "test_snow_pixel2byte_dsi_reset.v" `include "test_snow_pixel2byte_dsi_trans.v" `else `include "test_snow_pixel2byte_csi2_trans.v" `include "test_snow_pixel2byte_csi2_reset.v" `endif ............... .... и вызов ........... @(posedge pix_clk_i); byte_log_en = 1; start_vid = 1; $display(" test_hsync_front_porch : %d \n", hfront_porch); $display(" test_hsync_width : %d \n", hsync_pulse); $display(" test_hsync_back_porch : %d \n", hback_porch); $display(" test_h_width : %d \n", act_pix); $display(" test_v_height : %d \n", total_line); $display(" test_vsync_front_porch : %d \n", vfront_porch); $display(" test_vsync_width : %d \n", vsync_pulse); $display(" test_vsync_back_porch : %d \n", vback_porch); mon_en = 1; test_snow_pixel2byte_csi2_trans; `ifdef DSI_RESET_TEST1 byte_log_en = 0; start_vid = 1; mon_en = 1; test_snow_pixel2byte_dsi_reset; `endif ................. В test_snow_pixel2byte_csi2_trans.v определен такой task // ========================================================================= // Filename: test_snow_pixel2byte_csi2_trans.v // Copyright(c) 2017 Lattice Semiconductor Corporation. All rights reserved. // ========================================================================= //`ifdef CSI2_TEST1 task test_snow_pixel2byte_csi2_trans; begin fork `ifdef MISC_ON if (data_type !== 6'bzz_zzz) // 20191217 while((frame_cnt !== num_frames)) begin ......................... Насколько я понимаю перед begin должны быть перечислены input и output для даного task, но их нет. Все нужные файлы включены в .do файл, использую vlog -sv -work lib filename.v чтобы добавить исходник к тестбенчу ModelSim ругается, не видит frame_cnt # ** Error: ../ipcore/pix2byte/pixel2byte_eval/testbench/test_snow_pixel2byte_csi2_trans.v(83): (vlog-2730) Undefined variable: 'frame_cnt'. # ** Error: ../ipcore/pix2byte/pixel2byte_eval/testbench/test_snow_pixel2byte_csi2_trans.v(83): (vlog-2730) Undefined variable: 'num_frames'. ###### ../ipcore/pix2byte/pixel2byte_eval/testbench/test_snow_pixel2byte_csi2_trans.v(84): @(posedge eof); # ** Error: ../ipcore/pix2byte/pixel2byte_eval/testbench/test_snow_pixel2byte_csi2_trans.v(84): (vlog-2730) Undefined variable: 'eof'. Наверное есть какой-то нюанс, который мне не очевиден, я все же думаю автор этого теста проверял что генерирует wizard и запускал свой тест. Оригинального DO файла нет, он не сгенирирован wizard-ом. Подскажите пожалуйста, какая была задумка у автора этого дизайна, как task должен видеть переменные из главного модуля?
-
Всем привет. Мы проводим стримы по 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:
-
Импорт типа данных из интерфейса
Perdachillo posted a topic in Языки проектирования на ПЛИС (FPGA)
Всем привет. Пытаюсь передать параметризированную структуру между модулями и поскольку "parameter type" в Quartus 18.1 не работает, я хочу сделать это через интерфейс. Описываю его в отдельном файле, создаю инстанс в топ модуле, а во вложенном модуле пытаюсь вытащить из него тип данных. Выглядит это так: interface intf_WITHSTRUCT #(WIDTH=8); typedef struct packed{ logic val; logic [WIDTH-1:0] cnt; } st_INSIDE_INTF; st_INSIDE_INTF struct_inst; endinterface: intf_WITHSTRUCT module top (output logic [7:0] ocnt); intf_WITHSTRUCT #(.WIDTH(8)) interface_inst(); test i_test ( .clk(clk_125MHz), .rst(prb_rst), .blabla(interface_inst), .ocnt(ocnt) ); endmodule: top module test ( input clk, input rst, intf_WITHSTRUCT blabla, output logic [7:0] ocnt ); typedef blabla.st_INSIDE_INTF st_INSIDE_INTF_import; // Вытаскивю структуру st_INSIDE_INTF_import new_struct_inst; // Создаю инстанс [email protected](posedge clk or posedge rst) if(rst) new_struct_inst <= '0; else new_struct_inst.cnt <= new_struct_inst.cnt + 1'b1; [email protected](posedge clk or posedge rst) if(rst) ocnt <= '0; else ocnt <= new_struct_inst.cnt; endmodule: test В результате получаю ошибку: Error (10733): Verilog HDL error at test.sv(17): cnt is not declared under this prefix В чем может быть ошибка? Что странное, если во вложенном модуле я присваиваю структуре (которая в интерфейсе) значения, то ошибки не возникает. На мой взгляд не логичное поведение- 10 replies
-
- systemverilog
- interface
-
(and 1 more)
Tagged with:
-
Создание параметра определённого типа
Nick_K posted a topic in Языки проектирования на ПЛИС (FPGA)
Доброго времени суток. Проколупавшись целый день над вопросом решил обратиться к гуру. Есть ли какой-то способ создать типизированный параметр? В моём случае имеется enum тип вида: typedef enum byte {mon, tue, wed, thu, fri} weekdays_t; Но когда я пытаюсь сделать параметр такого типа, ничего не выходит. Вернее мне нужен параметр длинной n таких типов. Может кто-то сталкивался и есть решение (либо уже переработал...) Допустим получится создать массив с указанным типом. Ну или просто двумерный массив-параметр. Дальше загвоздка в его объявлении. Во всех случаях присвоение происходит поэлементно каждому элементу массива и некое дефолтное значение: parameter [7:0] byte_pattern_p [14:0] = '{1:'1, 2:'1, default:0}; Но что если мне нужно присвоить константы некому диапазону значений, коих к примеру 30 штук. Не писать же каждый номер и значение... Ну или просто списком задавать, тоже неудобно если элементов за 200 заваливает. Заранее спасибо за ответы -
Массив параметризируемых интерфейсов
Tik31 posted a topic in Языки проектирования на ПЛИС (FPGA)
Доброго времени суток. Не удается реализовать конструкцию, позволяющую сгенерирвать массив с интерфейсами, каждый из которых может быть настроен с помощью своих параметров. По задумке необходимо подключить слейвы/мастера к интерконнекту. В проекте предполагаются абоненты с разными параметрами интерфейсов (в частности разрядность шины). Передавать шины в интерконнект хочется массивом, а внутри уже подключать нужный к нужному. Возможно есть interface BUS #( parameter int asize = 32, parameter int dsize = 32 ); logic [asize-1:0] addr; logic [asize-1:0] data; endinterface; module top; BUS #( .asize (), .dsize () ) buses [0:1] (); interconnect inter_i ( .slaves(buses) ); slave1 slv1_i ( .slave(buses[0]) ); slave1 slv1_2 ( .slave(buses[1]) ); endmodule -
Простой вопрос про инкремент
MaratZuev posted a topic in Среды разработки - обсуждаем САПРы
Всем добра. Столкнулся с непонятной мне вещью: logic reset; logic [5:0] cnt; always_ff @(posedge clk) begin cnt <= reset ? '0 : cnt + 1; end Работает, но always_ff @(posedge clk) begin cnt <= reset ? '0 : cnt++; end нет. Отсылка к стандарту или куда-либо ещё приветствуется. -
Добрый день. Возник вопрос, как в модельсим передать между модулями упакованную структуру одно поле которой параметризировано? Если пишу так, то он ругается на то что структура не определена (логично): module input_processing #( parameter WORK_WIDTH = 18 )( input logic ireset, input logic iclk, output st_TAG port_tag, ); typedef struct packed{ logic throw; logic R_pack; logic H_pack; logic [$clog2(WORK_WIDTH)-1:0] pad; logic [15:0] slice_len; } st_TAG; ** Error: near "port_tag": syntax error, unexpected IDENTIFIER, expecting ')'. Если так, то говорит, что не определен параметр (тоже логичо): typedef struct packed{ logic throw; logic R_pack; logic H_pack; logic [$clog2(WORK_WIDTH)-1:0] pad; logic [15:0] slice_len; } st_TAG; module input_processing #( parameter WORK_WIDTH = 18 )( input logic ireset, input logic iclk, output st_TAG port_tag, ); ** Error: (vsim-3043) Unresolved reference to 'WORK_WIDTH' in $root.WORK_WIDTH. На самом деле у меня уже возникала похожая проблема, только не со структурой, а с функцией. Возникала ошибка, когда я пытался рассчитать размерность порта с помощью функции определенной в теле модуля. Я нахожу логику в ошибках modelsim, но если он запрещает заходить в тело модуля при объявлении портов, то должна быть возможность определить структуру/функцию в описании портов, чтобы использовать их там. Или нет? Забавно, что Quartus ошибку не выдает (по крайней мере с функциями), то есть там получается другая область видимости. Вы не находите странным такую разницу в подходах Quartus 17 и Modelsim 10.4b? Да я в принципе могу определить выход просто как разрядность и в теле присвоить ему упакованную структуру, но потом при изменении структуры мне разрядность этого выхода придется постоянно менять.
-
Добрый вечер! подскажите мне, начинающему инженеру-програмисту на systemVerilog. начальник дал задание: попробовать реализовать каскадную схему децимирующего, симметричного КИХ фильтра(в англ. литературе что то типа symmetric systolic multiply-accumulate filter). схема по типу той что на картинке, только с использованием предсумматора, чтобы уменьшить кол-во умножилок. это решаемая задача?? не могу даже найти схему. заранее всем спасибки!!!
- 3 replies
-
- ких
- симметричнй
-
(and 4 more)
Tagged with:
-
Добрый день. Есть такая задача: на вход модуля поступает массив параметров. Необходимо этот массив обработать и на его основе получить другой массив параметров, который в свою очередь будет использоваться для generate блоков. Обычно, для этого я писал тело функции без входных/выходных сигналов, внутри которой производил расчет. А потом параметру присваивал эту функцию. Для простого примера: function [31:0] calculate_free_gbe ( ); begin calculate_free_gbe = '0; for (int i = 0; i < N_GBE; i++) begin if (FREE_GBE[i] == 1) calculate_free_gbe = calculate_free_gbe + 1; end return calculate_free_gbe; end endfunction parameter N_FREE_GBE = calculate_free_gbe(); Выглядит, как костыль, но на практике все считалось Квартусом перед синтезом и на основе результата уже синтезировалась логика. Но сейчас мне понадобилось вытащить из функции несколько значений (причем разных по размерам) и присвоить их параметрам. Как можно это реализовать? Я попытался сделать выходные сигналы у функции, но вот как их потом присвоить параметру? Может вообще есть какой то другой вариант области в которой можно производить вычисления и создавать новые параметры?
- 15 replies
-
- systemverilog
- function
-
(and 1 more)
Tagged with:
-
Всем привет! Возможно, вопрос обсуждался, но мне найти не удалось. Суть в следующем. Есть проект, успешно собирается и даже работает. Но при синтезе возникают тонны предупреждений такого рода: WARNING: [Synth 8-3331] design <...> has unconnected port <...>. Выглядит угрожающе, но на деле по нетлисту (схематику) видно, что сигналы-то на месте, всё подключено. Анализ показывает, что почти все они относятся к сигналам интерфейсов. И похоже, что синтезатор ругается на сигналы модпортов интерфейса, которые не используется в том или ином модуле. Т.е. насколько понимаю, картина такая: есть интерфейс, у него есть модпорты m0, m1, s0, модпорт m0 подключается к модулю master0, модпорт m1 - к модулю master1, а модпорт s0 - к модулю slave0. Получается, что интерфейс прокинут во все модули, но часть сигналов, которые относятся к другим модпортам, естественно в данном конкретном модуле не подключена - например, в модуле master0 не подключены сигналы модпоротов m1 и s0. Получается, что ругань как бы не по делу. Собственно вопрос: как с этим бороться, т.к. подобные предупреждения выглядят неприятно?
- 3 replies
-
- interface
- systemverilog
-
(and 2 more)
Tagged with:
-
Доюрый день! Столкнулся с необходимостью работы с массивом констант в виде упакованно-неупакованных конструкций. вот пример того, что мне необходимо: localparam int N = 5; localparam int W = 18; const logic [ADDR_W-1 : 0] hard_point [N] = '{16, 17, 18, 19, 20}; на такую запись Квартус вываливает предупреждения: Warning (10030): Net "hard_point.data_a" at mem_reader.sv(61) has no driver or initial value, using a default initial value '0' Warning (10030): Net "hard_point.waddr_a" at mem_reader.sv(61) has no driver or initial value, using a default initial value '0' Warning (10030): Net "hard_point.we_a" at mem_reader.sv(61) has no driver or initial value, using a default initial value '0' Код работает исправно, но эти варнинги мне непонятны и хотелось бы с ними разобраться, но не совсем понятно, что от меня требует Квартус. Я понимаю, что необходимо указывать конкретную размерность данных, но затрудняюсь с синтаксисом. Прошу помощи.
- 24 replies
-
- systemverilog
- packed
-
(and 2 more)
Tagged with:
-
Доброго времени суток! Для облегчения жизни при сборке модулей в готовую систему решил сделать свой модуль как отдельное IP ядро с всеми необходимыми настройками параметров, включая размножение внутренних компонентов обработки, которые состоят из входного сигнала, логики+БРАМ, и выходной порт AXI. Всё написано на SystemVerilog и "выходной" порт AXI запихнут в отдельный интерфейс. Правдами и неправдами сумел собрать IP и договорится с bd что это и вправду компонент с AXI шинами (пришлось перегенерировать кучу портов и создать массу ненужных параметров, те которые с ID и USER). Для удобства создал параметр, который говорит сколько внутри размножено модулей и соответственно сколько входных сигналов и выодных AXIшин должно быть прокинуто. С помощью настройки Interface presence указал когда должны появляться порты (коих 32 штуки) по условию ($P_COMPONENT_NUM >N) для входных сигналов и AXI. Входные порты конфигурируются нормально без каких бы то ни было вопросов, все неиспользующиеся подвешиваются на 0. Но вот AXI начинает творить чудеса. BDувидел, что это AXI и что у него сконфигурированы все порты в соответствии с проприетарным интерфейсом "aximm", да вот только он пытается подключить все 32 AXI порта к несуществующим сигналам. В коде интерфейс сгенерированного топ файла IPядра выглядит где-то так: Тут ничего неординароного, а вот дальше генератор пытается создать и подключить все AXI порты: aximm S_AXI_0(); // Порт 0 присутствует assign S_AXI_0.WLAST = s_axi_0_s_axi_wlast; assign S_AXI_0.BREADY = s_axi_0_s_axi_bready; assign S_AXI_0.AWLEN = s_axi_0_s_axi_awlen; ... aximm S_AXI_1(); // Порт 1 присутствует assign S_AXI_1.WLAST = s_axi_1_s_axi_wlast; assign S_AXI_1.BREADY = s_axi_1_s_axi_bready; assign S_AXI_1.AWLEN = s_axi_1_s_axi_awlen; ... aximm S_AXI_2(); // Порт 2 отсутствует (не сконфигурирован) assign S_AXI_2.WLAST = s_axi_2_s_axi_wlast; assign S_AXI_2.BREADY = s_axi_2_s_axi_bready; assign S_AXI_2.AWLEN = s_axi_2_s_axi_awlen; ... aximm S_AXI_3(); // Порт 3 отсутствует (не сконфигурирован) assign S_AXI_3.WLAST = s_axi_3_s_axi_wlast; assign S_AXI_3.BREADY = s_axi_3_s_axi_bready; assign S_AXI_3.AWLEN = s_axi_3_s_axi_awlen; ... // И так все 32 порта из которых реально входит только 2 первых Ну и дальше идёт подключение к моему сгенерированному IP ядру. top_component inst ( .i_clk(i_clk), .s_axi_aclk(s_axi_aclk), .s_axi_aresetn(s_axi_aresetn), .s00_axi_0_s00_axi_araddr(s00_axi_0_s00_axi_araddr), .s00_axi_0_s00_axi_arprot(s00_axi_0_s00_axi_arprot), .s00_axi_0_s00_axi_arready(s00_axi_0_s00_axi_arready), ... // Конфигурация AXI Lite. Здесь всё нормально .S_AXI_0(S_AXI_0), // Подключён существующий порт .S_AXI_1(S_AXI_1), // Подключён существующий порт .S_AXI_2(S_AXI_2), // Подключён несуществующий порт. Который просто объявлен в топе .S_AXI_3(S_AXI_3), // Подключён несуществующий порт. Который просто объявлен в топе ... // И так далее до 31-го порта .i_signal_0(i_signal_0),// Подключён существующий вход .i_signal_1(i_signal_0),// Подключён существующий вход .i_signal_2(1'B0), // Подключён несуществующий вход. Который просто объявлен в топе .i_signal_3(1'B0), // Подключён несуществующий вход. Который просто объявлен в топе ... // И так далее до 31-го порта ); Как избежать такой ситуации? Нужно дополнительно указать какие-то параметры или вручную создать порты AXI? Этот файл генерируется автоматические и Xilinxпредупреждает: // DO NOT MODIFY THIS FILE.
- 40 replies
-
- block design
- systemverilog
-
(and 1 more)
Tagged with:
-
Доброго всем пятничного! Либо уже устал к концу недели, либо ещё что, но не могу понять в чём дело: 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
-
Здравствуйте, настал тут у меня момент отупения (всю неделю). Нужно реализовать асинхронный энкодер для параметризируемого регистра сдвига. Нужно контролировать фронт сигнала - то есть перепад подряд идущих единиц, пока не встретится стабильный ноль. Я написал такую функцию для преобразования входного потока, но она синтезируется в какую-то ерунду: function logic my_encoder( input logic [6 : 0] i_encode ); casez (i_encode) // приоритетный выбор "до первого ноля" 7'b??????1: return 3'b000; 7'b?????10: return 3'b001; 7'b????100: return 3'b010; 7'b???1000: return 3'b011; 7'b??10000: return 3'b100; 7'b?100000: return 3'b101; 7'b1000000: return 3'b110; default: return 3'b111; endcase Так как функции не параметризируются, а входной регистр может быть разной длинны, приходится по-рагульному встраивать в код: parameter p_length = 3; // анализ 3-х бит данных logic [3 : 0] r_data; // иходной вектор wire logic [1 : 0] r_data_encoded; // выходные декодированные данные assign {r_data_encoded} = my_encoder(r_data[p_length - 1 : 0]); Приоритетный перебор "менял местами" - ничего не помогло (перечисление наоборот). Подскажите возможное решение. А лучше почему данный Кейс финтезируется в какой-то бред (у меня всегда 1-й бит r_data_encoded подтянут на землю). З.Ы. Так же пробовал абстрагироваться от остальных значений и детектировать только наиболее раннее значение фронта, результат таков же: casez (i_encode) 7'b??????1: return 3'b000; 7'b?????10: return 3'b001; 7'b????10?: return 3'b010; 7'b???10??: return 3'b011; 7'b??10???: return 3'b100; 7'b?10????: return 3'b101; 7'b10?????: return 3'b110; default: return 3'b111; endcase
-
Доброго времени, уважаемые. В процессе написания кода возникла необходимость сделать user-френдли компонент с упрощенным редактированием. В чём основная суть: создаётся в начале файла несколько структур, в которые "пользователь" (человек, далее работающий с кодом) может добавлять одномерные векторы (рандомной длинны), нужное количество. В упрощённом варианте первая структура несёт все елементы, во второй указано только то, что подлежит сбросу по определённому ивенту. module component_1(...); typedef struct packed{ logic [1:0] first; logic [0:0] second; logic [2:0] third; } t_elements; t_elements common_elements; typedef struct packed{ logic [0:0] second; } t_reset; t_reset reset_elements; always_ff @(posedge clk) if (reset == 1) for(int i=0; i < $size(t_elements); i++) // тут пошла отсебятина ибо не представляю как реализовать if (reset_elements.i == common_elements.i) common_elements.i <= '0; Как сделать референс/перечисление/другой вариант, чтобы автоматизировать задачу и не заставлять юзера лезть в дебри кода, для правки сбрасываемых компонентов? Возможно есть вариант с одной структурой и какими-то указателями. Я уже и через enum пробовал вытащить имена и думал за union. Всё какое-то громоздкое и неработающее.
-
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 -
Генерация единичной матрицы на SV
TamRazZ posted a topic in Языки проектирования на ПЛИС (FPGA)
Добрый день! Подскажите, пожалуйста, простой и доступный способ реализации на SV функции генерации единичной матрицы. Вот набросок моего видения этой функции: function automatic logic[size-1:0][size-1:0] eye (input int size); for (int i = 0; i < size; i++) for (int j = 0; j < size; j++) eye[i][j] = (i == j); endfunction Понятно, что компилятор не видит size в шапке объявляемой функции. Не понятно, как описать функцию, у которой размерность выходного аргумента зависит входного аргумента.- 4 replies
-
- sv
- systemverilog
-
(and 3 more)
Tagged with: