|
|
  |
FAQ по языкам описания аппаратуры |
|
|
|
Jul 9 2015, 09:43
|

Группа: Участник
Сообщений: 5
Регистрация: 7-07-15
Пользователь №: 87 472

|
Уважаемые знатоки Verilog, не могли бы Вы подсказать ответы на волнующие меня вопросы, или дать ссылку на источник информации, где можно найти эти ответы. 1) на одном украинском сайте выложена статья про reusable code, там в качестве примера приводится АЛУ. там перед (вызовом модуля) module instantiation написано следующее ALU #(size_A, size_B) ALU_DUT , что это за задержка такая #(size_A, size_B)? size_A и size_B явл-ся параметрами вызываемого модуля. В этой же статье не совсем понятно что означает сие объявление reg [6*8:0] _Mode_names [3:0]; 2) необходимо реализовать устройство на синхронной логике, реагирующее по фронту тактовой частоты и асинхронным reset и En. Вопрос заключается в следующем, поскольку мне важна последовательность назначений, можно ли использовать блокирующие назначения внутри конструкции always??? Согласно статье Сергея Емеца за 2001 год - "Если в блоке требуется провести последовательное исполнение операторов, следует применять блокирующий тип присвоения". Я полагаю, таким образом у меня появятся триггеры-защелки, как на Ваш взгляд было бы более качественно(меньшие аппаратные затраты, более высокое время исполнения) реализовать этот модуль? always @(posedge clk or negedge reset) if (!reset) or (AMCount == 1) result <= DATA_WIDTH_out'b0; else begin if (En) begin // использовали блокирующее присвоение R = R + (((C >> 56) & 0xFF) * 113); R = R + (((C >> 48) & 0xFF) * 61); R = R + (((C >> 40) & 0xFF) * 23); R = R + (((C >> 32) & 0xFF) * 131); R = R + (((C >> 24) & 0xFF) * 79); R = R + (((C >> 16) & 0xFF) * 91); R = R + (((C >> 8) & 0xFF) * 47); R = R + (((C & 0xFF) * 157); result = R % AMCount;
end end
3) Если у меня между аппаратными блоками передаются данные с типом структура T размером 18 байт , в которую входит набор элементов-данных (1байт.1байт.8байт.8байт.2байта.8байт) мне необходимо эту структуру передавать по шине, соответствующей размерности, а уже внутри моего блока-приемника разделить эту шину, на интересующие меня сигналы(wire) ? Или на практике это реализуется несколько иначе? Если не затруднит, не могли бы скинуть ссылку, где описывается данная проблема.
|
|
|
|
|
Jul 9 2015, 10:32
|
Частый гость
 
Группа: Свой
Сообщений: 134
Регистрация: 9-11-12
Из: г. Брянск
Пользователь №: 74 311

|
Цитата(Radov Dmitrii @ Jul 9 2015, 12:43)  там перед (вызовом модуля) module instantiation написано следующее ALU #(size_A, size_B) ALU_DUT , что это за задержка такая #(size_A, size_B)? size_A и size_B явл-ся параметрами вызываемого модуля. Это реализация экземпляра параметризованного модуля ALU, имя экземпляра ALU_DUT. В скобках после "решетки" задаются параметры экземпляра. Подробнее можно почитать тут http://www.kit-e.ru/articles/circuit/2008_12_121.phpЦитата(Radov Dmitrii @ Jul 9 2015, 12:43)  В этой же статье не совсем понятно что означает сие объявление reg [6*8:0] _Mode_names [3:0]; Объявлен массив 48-ми разрядных слов _Mode_names, состоящий из 4-х элементов. Чтобы обратиться, например, к третьему элементу массива, нужно записать так _Mode_names[2] <= 48'hFFFF_FFFF_FFFF; Цитата(Radov Dmitrii @ Jul 9 2015, 12:43)  Если у меня между аппаратными блоками передаются данные с типом структура T размером 18 байт , в которую входит набор элементов-данных (1байт.1байт.8байт.8байт.2байта.8байт) мне необходимо эту структуру передавать по шине, соответствующей размерности, а уже внутри моего блока-приемника разделить эту шину, на интересующие меня сигналы(wire) ? Или на практике это реализуется несколько иначе? Если не затруднит, не могли бы скинуть ссылку, где описывается данная проблема. У Вас получается 1+1+8+8+2+8 = 28 байт, а не 18, если я правильно понял. Можно, конечно, сделать широкую шину и передавать одним тактом. Но, если "время терпит", лучше передать последовательно несколькими словами. Или вообще, по одной линии. В приемнике сдвигаете все в один регистр и дальше используете, как нужно. Погуглите термины "сериализация" и "десериализация". В сети также есть примеры на HDL. Например, на Verilog http://stackoverflow.com/questions/2901655...o-8-verilog-hdl
|
|
|
|
|
Jul 14 2015, 10:36
|

Группа: Участник
Сообщений: 5
Регистрация: 7-07-15
Пользователь №: 87 472

|
Можно ли внутри одного модуля чередовать комбинационные и синхронные блоки always? Можно ли внутри блока always реагирующего по фронту сигнала использовать блокирующие присваивания? Можно ли в Quartus 2 задавать 64-битным переменные(64-bit wide binary number)? Так возможно -> C = 64'b0 ?
|
|
|
|
|
Jul 14 2015, 11:41
|
Частый гость
 
Группа: Свой
Сообщений: 134
Регистрация: 9-11-12
Из: г. Брянск
Пользователь №: 74 311

|
Цитата(Radov Dmitrii @ Jul 14 2015, 13:36)  Можно ли внутри одного модуля чередовать комбинационные и синхронные блоки always? Можно, порядок следования блоков always в модуле ни на что не влияет. Цитата(Radov Dmitrii @ Jul 14 2015, 13:36)  Можно ли внутри блока always реагирующего по фронту сигнала использовать блокирующие присваивания? Можно. Вот полезная статья по теме http://svo.2.staticpublic.s3-website-us-ea...og/assignments/Цитата(Radov Dmitrii @ Jul 14 2015, 13:36)  Можно ли в Quartus 2 задавать 64-битным переменные(64-bit wide binary number)? Так возможно -> C = 64'b0 ? Здесь Вы присваиваете переменной 64-битное значение, но при этом определяете только один бит из 64-х. Тут надо смотреть, как поведет себя Quartus, во что такая запись синтезируется. Лучше, конечно, определить все разряды. Я бы написал так С = 64'h00_00_00_00_00_00_00_00; Громоздко, но зато однозначно. Можно еще так попробовать С = 64'd0; Но Quartus, кажется, считает десятичные числа 32-х разрядными. Поэтому старшие 32 бита опять могут повиснуть в воздухе. Попробуйте разные варианты, посмотрите как оно получается в железе.
|
|
|
|
|
Jul 14 2015, 11:52
|
Частый гость
 
Группа: Свой
Сообщений: 134
Регистрация: 9-11-12
Из: г. Брянск
Пользователь №: 74 311

|
А еще лучше, как товарищ des00 выше подсказал, написать С = {64{1'b0}}; Так будет более правильно. Цитата(des00 @ Jul 14 2015, 14:50)  Вы не правы. IEEE Std 1364-2001 -> 2. Lexical conventions -> 2.5 Numbers -> 2.5.1 Integer constants Возможно, как-то всегда избегал подобных записей. Спасибо за подсказку.
|
|
|
|
|
Jul 14 2015, 12:05
|
Вечный ламер
     
Группа: Модераторы
Сообщений: 7 248
Регистрация: 18-03-05
Из: Томск
Пользователь №: 3 453

|
Цитата(dima32rus @ Jul 14 2015, 18:52)  написать С = {64{1'b0}}; Так будет более правильно. Это лучше предотвращением предупреждения синтезатора в случае если длинна вектора задается параметром и может плавать. Т.е. {PIPA{1'b0}} - корректная конструкция, PIPA'd0 - нет. Но диапазон таких "красивых" констант ограничен. Цитата Возможно, как-то всегда избегал подобных записей. Спасибо за подсказку. Ну и зря. Стандарт писали умные люди. Сами посудите, вы жестко задаете разрядность RHS, зачем писать нулевые старшие элементы? Вот если бы константа была безразмерная, то да,
--------------------
|
|
|
|
|
Jul 14 2015, 12:43
|

Группа: Участник
Сообщений: 5
Регистрация: 7-07-15
Пользователь №: 87 472

|
upd.
В Квартусе, начиная с 14 версии задавать 64-bit wide binary number можно. Я не правильно сформулировал вопрос.
Если кто знает, не подскажите как выделить из 64-разрядной переменной, младшие/старшие 8 разрядов? Может ли integer x быть 64-разрядным? Верней integer, по всей видимости, по умолчанию это 32-разрядное целое число, а как задать его 64-разрядным?
upd upd Спасибо большое за ответы.
Сообщение отредактировал Radov Dmitrii - Jul 14 2015, 12:47
|
|
|
|
|
Jul 14 2015, 12:48
|
Вечный ламер
     
Группа: Модераторы
Сообщений: 7 248
Регистрация: 18-03-05
Из: Томск
Пользователь №: 3 453

|
Цитата(Radov Dmitrii @ Jul 14 2015, 20:43)  Если кто знает, не подскажите как выделить из 64-разрядной переменной, младшие/старшие 8 разрядов? Может ли integer x быть 64-разрядным? Верней integer, по всей видимости, по умолчанию это 32-разрядное целое число, а как задать его 64-разрядным? 1. pipa <= popa[7:0]; pipa <= popa[63:56]; 2. integer может быть только 32 бита. А вот вектор может быть 2^16 битным. ЗЫ. Не хотите читать стандарт, прочитайте любой другой нормальный материал по языку который собираетесь использовать для работы. Уважайте себя, не поднимайте насмех.
--------------------
|
|
|
|
|
Jul 14 2015, 12:57
|

Группа: Участник
Сообщений: 5
Регистрация: 7-07-15
Пользователь №: 87 472

|
upd.
В Квартусе, начиная с 14 версии задавать 64-bit wide binary number можно. Я не правильно сформулировал вопрос.
Суть вопроса(опять криво сформулированного): У меня есть переменная(64бит), у которой по очереди берут по одному байту начиная со старшего, умножают на некоторое число, затем результат отправляют в другую переменную(полагаю, что тип reg, иначе не получится сохранить полученные промежуточные значения)
dima32rus: спасибо за ссылку и ответы, но я эту статью прочёл в прошлый раз, когда Вы мне её прислали. Меня слегка сбил материал с Марсохода, я видимо не так понял, но мне показалось что там прослеживалась логика если по уровню то комб. логика и блокирующие присваивании если по фронту то синх. лог и неблок. присваивания.
des00: спасибо за ответ. Простите не успел отредактировать вопрос, т.е. стереть вопросы. Стандарт прочту.
upd upd Спасибо большое за ответы.
|
|
|
|
|
Jul 28 2015, 05:54
|
Местный
  
Группа: Участник
Сообщений: 368
Регистрация: 18-04-11
Из: Город-герой Москва
Пользователь №: 64 451

|
Всем доброго времени суток. Не совсем знал куда писать, так что напишу сюда. Сталкнулся с такой проблемой - написал ядро (avalon - slave) для NiosII. Приведу несколько строк кода: Код wr_tx_udp_data_LOW <= '1' when address = "1000" and wr_en='1' else '0'; -- 8 TX_UDP_DATA_LOW wr_tx_udp_data_HIGH <= '1' when address = "1001" and wr_en='1' else '0'; -- 9 TX_UDP_DATA_HIG . . . process(clk50, resetn) begin if rising_edge(clk50) then if wr_tx_udp_data_LOW = '1' then tx_udp_data_reg(31 downto 0) <= writedata(31 downto 0); else tx_udp_data_reg <= tx_udp_data_reg; end if;
if wr_tx_udp_data_HIGH = '1' then tx_udp_data_reg(63 downto 32) <= writedata(31 downto 0); else tx_udp_data_reg <= tx_udp_data_reg; end if; Имеется 64-х разрядный буфер tx_udp_data_reg, в него необходимо записать данные с 32-х разрядной шины writedata. Я решил записать сначала младшие 4 байта, затем страршие 4 байта. Но как оказалось после компиляции запись происходит лишь в старшие 4 байта. После этого я закоментил строки: Код if wr_tx_udp_data_HIGH = '1' then tx_udp_data_reg(63 downto 32) <= writedata(31 downto 0); else tx_udp_data_reg <= tx_udp_data_reg; end if; Запись как и положено произошла в младшие 4 байта. Я сделал вывод, что компилятор оптимизирует логику в первом коде, но почему?
|
|
|
|
|
Jul 28 2015, 07:14
|
Местный
  
Группа: Участник
Сообщений: 368
Регистрация: 18-04-11
Из: Город-герой Москва
Пользователь №: 64 451

|
Stewart Little, спасибо за совет, помогло. Правда напсал чуть короче: Код if wr_tx_udp_data_LOW = '1' then tx_udp_data_reg(31 downto 0) <= writedata(31 downto 0); elsif wr_tx_udp_data_HIGH = '1' then tx_udp_data_reg(63 downto 32) <= writedata(31 downto 0); else tx_udp_data_reg <= tx_udp_data_reg; end if; Но почему всё же первый вариант не прокатил?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|