Вадим Н. 1 7 декабря, 2022 Опубликовано 7 декабря, 2022 (изменено) · Жалоба Требуется мультиплексор для задачи которая в общем описана в testbench ниже. Сначала я интуитивно всё это нарисовал и всё казалось нормально (см. первый вариант). Но потом стало ясно что ни кто так не делает. Поискал по форуму всё с "mux" (в частности). Написал вариант генерирующий мультиплексор (см. второй вариант). Spoiler module testbench(); initial begin $dumpfile("mux2.vcd"); $dumpvars(0, testbench); #100 $stop; end reg clk; initial clk = 1; always #5 clk = !clk; // некий аддер складывающий разные значения на каждом такте wire [7:0] a, b; reg [7:0] s; always @ (posedge clk) s <= a + b; // управляющий сигнал для мультиплексора reg t1, t2, t3; initial begin t1 = 1; t2 = 0; t3 = 0; forever @ (posedge clk) {t1, t2, t3} <= {t3, t1 ,t2}; end // входы мультиплексора reg [7:0] i, j, k; // для a reg [7:0] l, m, n; // для b initial begin i = 1; j = 10; k = 100; l = 101; m = 102; n = 103; end mux2 uut ( .t1 (t1), .t2 (t2), .t3 (t3), .i (i ), .j (j ), .k (k ), .l (l ), .m (m ), .n (n ), .a (a ), .b (b ) ); endmodule module mux2( input t1, input t2, input t3, input [7:0] i, input [7:0] j, input [7:0] k, input [7:0] l, input [7:0] m, input [7:0] n, output [7:0] a, output reg [7:0] b ); // 2 разных мультиплексора // первый вариант wire [7:0] a1,a2,a3; assign a = a1 | a2 | a3, a1 = t1 ? i : 0, a2 = t2 ? j : 0, a3 = t3 ? k : 0; // второй вариант always @ (*) case ({t1, t2, t3}) 'b100: b = l; 'b010: b = m; 'b001: b = n; default: b = 0; endcase endmodule С использованием for для генерации комбинаторной логики всё ясно, но тут управляющий сигнал по другому устроен. И переделывать его, вроде бы, нет оснований. Так что я case использовал. Может будут какие-нибудь замечания... правильно ли использовать always @ (*) ? Изменено 7 декабря, 2022 пользователем Вадим Н. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
litv 0 7 декабря, 2022 Опубликовано 7 декабря, 2022 · Жалоба http://ebook.pldworld.com/_eBook/FPGA/HDL/-Eng-/HDL Chip Design. A Practical Guide for Designing, Synthesizing and Simulating ASICs and FPGAs Using VHDL or Verilog (Douglas Smith).pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 33 7 декабря, 2022 Опубликовано 7 декабря, 2022 · Жалоба 11 hours ago, Вадим Н. said: Может будут какие-нибудь замечания И первый и второй варианты описания вполне рабочие и применяемые на практике, как и вариант с for. Но эти варианты логически неэквивалентны. И это надо учитывать при применении и анализе результатов синтеза. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sazh 8 7 декабря, 2022 Опубликовано 7 декабря, 2022 · Жалоба В 07.12.2022 в 07:15, Вадим Н. сказал: Требуется мультиплексор Может будут какие-нибудь если требуется мультиплексор, наверно его надо описывать как мультиплексор. В документе xst.pdf можно посмотреть. module mux_bus #(parameter w = 4, n = 4, nclog2 = $clog2(n) ) ( input [w*n-1:0] in_data, input [nclog2-1:0] sel, output [w-1:0] out_data ); assign out_data = in_data[sel*w +: w]; endmodule Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Вадим Н. 1 8 декабря, 2022 Опубликовано 8 декабря, 2022 · Жалоба litv, спасибо! ознакомился с "HDL Chip Design..." подход к изложению норм. Но есть нюанс. Spoiler // сначала было так case ({t1, t2, t3}) 'b100: b = l; 'b010: b = m; 'b001: b = n; default: b = 0; endcase // примерчик из книги товарища Дугласа J. Смита натолкнул меня на мысль что мне ноль то и не нужен; сделал как в книжке case ({t1, t2, t3}) 'b100: b = l; 'b010: b = m; 'b001: b = n; default: b = l; endcase // - внешне тоже самое в RTL // такие вариации: case ({t1, t2}) 'b10: b = l; 'b01: b = m; default: b = n; endcase // только хуже делают: в RTL появляется уровень комбинаторной логики с t1,t2,t3 /* и тут вспомнил у General Coding Guidelines Chapter 13: Recommended HDL Coding Styles* Altera рекомендует: If the value in the invalid cases is not important, specify those cases explicitly by assigning the X (don’t care) logic value instead of choosing another value. This assignment allows your synthesis tool to perform the best area optimizations. */ case ({t1, t2, t3}) 'b100: b = l; 'b010: b = m; 'b001: b = n; default: b = 'bx; // кое-что меняется, квартус пишет что используется на один логический элемент меньше но появляются предупреждения: вход t3 вообще не нужен, какие-то преобразования типов... // вобщем, напрашивается дальнейшая оптимизацичя: case ({t2, t3}) 'b00: b = l; 'b01: b = m; 'b10: b = n; default: // здесь собственно без 1 'bx - 32 разряда b = 1'bx; endcase /* итого, первый вариант самый программистский и читаемый последний самый экономичный, рекомендуемый Квартус-стайл-гвайдом */ * у меня нет этой книжки целиком, есть одна глава: General Coding Guidelines Chapter 13: Recommended HDL Coding Styles "FPGA\intel-Altera\Quartus II\Handbook\1 Design and Synthesis\qts_qii51007.pdf" RobFPGA, спасибо! вас понял. Точнее, понял оп чём речь когда прочитал про классификацию мультиплексоров в этом квартус-дизайн буке (см. выше) sazh, спасибо! это SV наверное, и уровень супер эрор-пруф прогрэмин. - не. я пока пешком ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yes 7 8 декабря, 2022 Опубликовано 8 декабря, 2022 · Жалоба в рамках занудства - книжка Смита написана в 1996 году, как думаете, поменялось ли что-то в этой области за почти 30 лет? btw: [sel*w +: w] это не SV, а Verilog 2001 ------------- upd: то есть, 1) код должен быть понятным, а чем меньше букв в описании, тем понятнее; 2) для стандартного узла всегда лучше использовать стандартное описание, а не колхозить индусский код Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
litv 0 8 декабря, 2022 Опубликовано 8 декабря, 2022 · Жалоба Хороший синтезатор оптимальную логику мультиплексоров нормально сделает сам. Например Synplify. Придерживаться лучше рекомендаций от производителя по реализации. Ибо в разных семействах ПЛИС есть отличия, которые могут сильно менять оптимальное решение. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 33 8 декабря, 2022 Опубликовано 8 декабря, 2022 · Жалоба 9 hours ago, Вадим Н. said: подход к изложению норм. Но есть нюанс. Маленький нюанс как раз и может испортить "бочку меда" ... или украсить "торт". Когда вы пишете // сначала было так case ({t1, t2, t3}) 'b100: b = l; 'b010: b = m; 'b001: b = n; default: b = 0; endcase // или case ({t1, t2, t3}) 'b100: b = l; 'b010: b = m; 'b001: b = n; default: b = 'bx; вы создаете мукс не на 3, а на 4 входа, каждый из которых выбирается логикой (декодером) от 3-х переменных. Вариант case ({t1, t2, t3}) 'b100: b = l; 'b010: b = m; 'b001: b = n; default: b = l; endcase создает мукс на 3 входа но тоже с декодером от 3-х переменных на входе Вариант case ({t2, t3}) 'b00: b = l; 'b01: b = m; 'b10: b = n; default: // здесь собственно без 1 'bx - 32 разряда b = 1'bx; endcase Тоже создает мукс на 3 входа но уже с декодером от 2-х переменных на входе. Но если у вас сигналы управления уже гарантированно ohe-hot то зачем тратить доп. логику на декодер. Есть еще вариант описания мукса для one-hot входов casez ({t2,t1,t0}) 3'b??1: b = l; 3'b?1?: b = m; 3'b1??: b = n; endcase // или инверсный вариант case (1'b1) t0: b = l; t1: b = m; t2: b = n; endcase Есть еще атрибуты full_case и parallel_case которые тоже влияют на результат синтеза. Например вариант с (* parallel_case *) case ({t2,t1,t0}) ... может отличатся по синтезу от варианта без этого атрибута. Так как без атрибута case синтезируется как приоритетное сравнение вариантов. Поэтому во что конкретно будет синтезироваться то или иное описание зависит как от стиля (так как не все описания эквивалентны по логике) так и от целевой платформы, атрибутов, констрейнов и опций оптимизации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Вадим Н. 1 9 декабря, 2022 Опубликовано 9 декабря, 2022 · Жалоба On 12/8/2022 at 3:16 PM, yes said: [sel*w +: w] это не SV, а Verilog 2001 точно! Хотя "IEEE Std 1364-2001" у меня всегда под рукой, как то именно раздел "part-select" до сих пор пропускал. А всё потому что там картинок нет при столь не очевидной схеме +, -, lsb, msb %) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sazh 8 9 декабря, 2022 Опубликовано 9 декабря, 2022 · Жалоба В 09.12.2022 в 06:48, Вадим Н. сказал: точно! Хотя "IEEE Std 1364-2001" у меня всегда под рукой, как то именно раздел "part-select" до сих пор пропускал. А всё потому что там картинок нет при столь не очевидной схеме +, -, lsb, msb %) Никакого волшебства. Простой подход "железячника". Описываете полный мультиплексор. И подаете на него полный набор входных данных. Приоритетность данных оставляете для себя (если надо, меняя содержимое входного вектора). Минимизация комбинаторной логики на откуп синтезатору. И все наглядно. Как вариант для рассмотрения : module mux_bus ( input [7:0] k, j, l, input t3, t2, t1, output [7:0] o_data ); wire [2:0] sel; wire [8*8-1:0] i_data; assign i_data = {8'd0, 8'd0, 8'd0, k, 8'd0, j, l, 8'd0}, sel = {t3, t2, t1}; assign o_data = i_data[sel*8 +: 8]; endmodule Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Вадим Н. 1 13 декабря, 2022 Опубликовано 13 декабря, 2022 · Жалоба sazh, попробовал примерчик свой переделать в таком стиле Spoiler /* mux_hardw.v Вариант явно объявленного мультиплексора RTL-представление менее понятное по проводам так как есть шина данных аж 64 бит и шина выбора почему то 6 бит а не 3 или 2, но результат синтеза по ресурсам точно тот же: ; Total logic elements ; 34 ; Total combinational functions ; 34 ; Dedicated logic registers ; 0 ; Total registers ; 0 ; Total pins ; 67 */ module testbench(); initial begin $dumpfile("mux_hardw.vcd"); $dumpvars(0, testbench); #100 $stop; end reg clk; initial clk = 1; always #5 clk = !clk; // некий аддер складывающий разные значения на каждом такте wire [7:0] a, b; reg [7:0] s; always @ (posedge clk) s <= a + b; // управляющий сигнал для мультиплексора reg t1, t2, t3; initial begin t1 = 1; t2 = 0; t3 = 0; forever @ (posedge clk) {t1, t2, t3} <= {t3, t1 ,t2}; end // входы мультиплексора reg [7:0] i, j, k; // для a reg [7:0] l, m, n; // для b initial begin i = 'd1; j = 'd10; k = 'd100; l = 'd101; m = 'd102; n = 'd103; end mux_hardw muxhw ( .t1 (t1), .t2 (t2), .t3 (t3), .i (i ), .j (j ), .k (k ), .l (l ), .m (m ), .n (n ), .a (a ), .b (b ) ); endmodule module mux_hardw ( input t1, input t2, input t3, input [7:0] i, input [7:0] j, input [7:0] k, input [7:0] l, input [7:0] m, input [7:0] n, output [7:0] a, output [7:0] b ); mux_bas uut ( .t1 (t1), .t2 (t2), .t3 (t3), .i0 (i ), .i1 (j ), .i2 (k ), .o_data (a ) ); mux_bas same_thingy ( .t1 (t1), .t2 (t2), .t3 (t3), .i0 (l ), .i1 (m ), .i2 (n ), .o_data (b ) ); endmodule module mux_bas ( input t1, t2, t3, input [7:0] i0, i1, i2, output [7:0] o_data ); wire [2:0] sel; wire [8*8-1:0] i_data; assign i_data = {8'd0, 8'd0, 8'd0, i2, 8'd0, i1, i0, 8'd0}, sel = {t3, t2, t1}; assign o_data = i_data[sel*8 +: 8]; // see 4.2.1 Vector bit-select and part-select addressing @ IEEE Standard Verilog 2001 endmodule в принципе, норм. Спасибо! А то я как то из тех примеров что в интернете встречал не понял как оставаясь в режиме one-hot, организовать выбор адреса. Расширить шину данных до соответствия трёхбитным адресам - мне эта идея вообще не пришла. Да я сейчас ещё не уверен что это практично может быть. Ну будет в арсенале там посмотрим. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 33 13 декабря, 2022 Опубликовано 13 декабря, 2022 · Жалоба 6 hours ago, Вадим Н. said: А то я как то из тех примеров что в интернете встречал не понял как оставаясь в режиме one-hot, организовать выбор адреса Как только вы объединяете ohe-hot в шину адреса вы тут же теряете преимущества ohe-hot добавляя слой логики для повторного декодирования этого адреса. Пару вариантов как описать мукс с использованием сигналов ohe-hot я приводил выше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sazh 8 13 декабря, 2022 Опубликовано 13 декабря, 2022 · Жалоба В 13.12.2022 в 07:06, Вадим Н. сказал: Расширить шину данных до соответствия трёхбитным адресам - мне эта идея вообще не пришла. Да я сейчас ещё не уверен что это практично может быть. Ну будет в арсенале там посмотрим. Если б работали в графическом редакторе. то пришла б. А вообще, с case надо быть осторожным (чтоб на защелки при описании не напороться). По идее, если не напрягает приоритетное мультиплексирование: assign o_data = t1 ? l : t2 ? j : t3 ? k : 8'h00; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться