|
|
  |
Безглитчевый мультиплексор клоков, Как правильно описывать, когда клоков больше чем 2 |
|
|
|
Jan 18 2010, 16:54
|
Вечный ламер
     
Группа: Модераторы
Сообщений: 7 248
Регистрация: 18-03-05
Из: Томск
Пользователь №: 3 453

|
Добрый день господа! Нужно сделать переключение 4-х клоков, без глитча во время переключения. Это можно сделать с помощью одного мультиплексора 4-в-1 вида CODE module clock_switcher4clock ( clkina , clkinb , clkinc , clkind , sel , // clkout = (sel == 0/1/2/3) -> clkina/clkinb/clkinc/clkind clkout );
//------------------------------------------------------------------------------------------------------ // //------------------------------------------------------------------------------------------------------
input logic clkina; input logic clkinb; input logic clkinc; input logic clkind; input logic [1 : 0] sel ; // clkout = (sel == 0/1/2/3) -> clkina/clkinb/clkinc/clkind output logic clkout;
//------------------------------------------------------------------------------------------------------ // //------------------------------------------------------------------------------------------------------
logic ctrla; logic ctrlb; logic ctrlc; logic ctrld;
logic [1:0] muxa; logic [1:0] muxb; logic [1:0] muxc; logic [1:0] muxd;
//------------------------------------------------------------------------------------------------------ // //------------------------------------------------------------------------------------------------------ // synthesis translate_off initial begin : ini muxa = '0; muxb = '0; muxc = '0; muxd = '0; end // synthesis translate_on //------------------------------------------------------------------------------------------------------ // //------------------------------------------------------------------------------------------------------
assign ctrla = ~sel[1] & ~sel[0] & ~muxb[1] & ~muxc[1] & ~muxd[1]; assign ctrlb = ~sel[1] & sel[0] & ~muxa[1] & ~muxc[1] & ~muxd[1]; assign ctrlc = sel[1] & ~sel[0] & ~muxa[1] & ~muxb[1] & ~muxd[1] ; assign ctrld = sel[1] & sel[0] & ~muxa[1] & ~muxb[1] & ~muxc[1];
always_ff @(negedge clkina) begin muxa <= {muxa[0], ctrla}; end
always_ff @(negedge clkinb) begin muxb <= {muxb[0], ctrlb}; end
always_ff @(negedge clkinc) begin muxc <= {muxc[0], ctrlc}; end
always_ff @(negedge clkind ) begin muxd <= {muxd[0], ctrld}; end
assign clkout = (muxa[1] & clkina) | (muxb[1] & clkinb) | (muxc[1] & clkinc) | (muxd[1] & clkind);
endmodule
или с помошью четырех мультиплексоров 2-в-1 вида CODE assign ctrla = ~sel & ~muxb[1]; assign ctrlb = sel & ~muxa[1];
always_ff @(negedge clkina) begin muxa <= {muxa[0], ctrla}; end
always_ff @(negedge clkinb) begin muxb <= {muxb[0], ctrlb}; end
assign clkout = (muxa[1] & clkina) | (muxb[1] & clkinb);
Мне кажеться что оба варианта должны быть работоспособны, но может быть я ошибаюсь. Подскажите какой вариант является более правильным? ЗЫ. Вариант использовать альтеровскую корку не предлагать, она не может покрыть всех вариантов используемых клоков %)
--------------------
|
|
|
|
|
Jan 18 2010, 17:16
|
Вечный ламер
     
Группа: Модераторы
Сообщений: 7 248
Регистрация: 18-03-05
Из: Томск
Пользователь №: 3 453

|
Цитата(SM @ Jan 18 2010, 11:06)  Более правильный вариант вообще четвертый, до четырех клоков расширяется по аналогии  спасибо, если я правильно понял в моем варианте нет асинхронных сбросов, как у вас и вы по сбросу ставите мультиплексор в определенное положение? Цитата(des333 @ Jan 18 2010, 11:09)  А тот, который Альтера предлашает, чем не годится?  этот вариант эквивалентен приведеном коду %) у меня ква для сыклона 3 сгенерировал CODE //synthesis_resources = clkctrl 1 //synopsys translate_off `timescale 1 ps / 1 ps //synopsys translate_on module switch_altclkctrl_9nd ( clkselect, ena, inclk, outclk) ; input [1:0] clkselect; input ena; input [3:0] inclk; output outclk; `ifndef ALTERA_RESERVED_QIS // synopsys translate_off `endif tri0 [1:0] clkselect; tri1 ena; tri0 [3:0] inclk; `ifndef ALTERA_RESERVED_QIS // synopsys translate_on `endif
wire wire_clkctrl1_outclk; wire [1:0] clkselect_wire; wire [3:0] inclk_wire;
cycloneiii_clkctrl clkctrl1 ( .clkselect(clkselect_wire), .ena(ena), .inclk(inclk_wire), .outclk(wire_clkctrl1_outclk) // synopsys translate_off , .devclrn(1'b1), .devpor(1'b1) // synopsys translate_on ); defparam clkctrl1.clock_type = "Global Clock", clkctrl1.ena_register_mode = "falling edge", clkctrl1.lpm_type = "cycloneiii_clkctrl"; assign clkselect_wire = {clkselect}, inclk_wire = {inclk}, outclk = wire_clkctrl1_outclk; endmodule //switch_altclkctrl_9nd //VALID FILE
// synopsys translate_off `timescale 1 ps / 1 ps // synopsys translate_on module switch ( clkselect, inclk0x, inclk1x, inclk2x, inclk3x, outclk);
input [1:0] clkselect; input inclk0x; input inclk1x; input inclk2x; input inclk3x; output outclk; `ifndef ALTERA_RESERVED_QIS // synopsys translate_off `endif tri0 [1:0] clkselect; `ifndef ALTERA_RESERVED_QIS // synopsys translate_on `endif
wire sub_wire0; wire sub_wire1 = 1'h1; wire sub_wire6 = inclk3x; wire sub_wire5 = inclk2x; wire sub_wire4 = inclk0x; wire outclk = sub_wire0; wire sub_wire2 = inclk1x; wire [3:0] sub_wire3 = {sub_wire6, sub_wire5, sub_wire2, sub_wire4};
switch_altclkctrl_9nd switch_altclkctrl_9nd_component ( .ena (sub_wire1), .inclk (sub_wire3), .clkselect (clkselect), .outclk (sub_wire0));
endmodule
этот компонент требует подачи части клоков с PLL, о чем ква радостно сообщает Цитата Error: inclk[2] port of Clock Control Block "switch_altclkctrl_9nd:switch_altclkctrl_9nd_component|clkctrl1" is driven by inclk2x~input, but must be driven by a PLL clock output Error: inclk[3] port of Clock Control Block "switch_altclkctrl_9nd:switch_altclkctrl_9nd_component|clkctrl1" is driven by inclk3x~input, but must be driven by a PLL clock output
--------------------
|
|
|
|
|
Jan 19 2010, 20:10
|
Знающий
   
Группа: Свой
Сообщений: 654
Регистрация: 24-01-07
Из: Воронеж
Пользователь №: 24 737

|
А почему бы не перевести все триггера на передний фронт. Тогда смеситель будет выглядеть так: Код assign gated_clks[i] = clk[i] | ena_r2[i];
assign clk_out = &gated_clks; и наверное, желательно, после каждого gated_clks поставить принудительно lcell.
|
|
|
|
|
Jan 19 2010, 20:19
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(dvladim @ Jan 19 2010, 23:10)  А почему бы не перевести все триггера на передний фронт. IMHO не суть важно, какой полярности логика и что на выходе, когда в процессе переключения нет ни одного клока. Цитата(dvladim @ Jan 19 2010, 23:10)  и наверное, желательно, после каждого gated_clks поставить принудительно lcell. Лучше грамотно обконстрейнить недра через set_max_delay
|
|
|
|
|
Jan 20 2010, 03:42
|
Вечный ламер
     
Группа: Модераторы
Сообщений: 7 248
Регистрация: 18-03-05
Из: Томск
Пользователь №: 3 453

|
Цитата(dvladim @ Jan 19 2010, 14:10)  А почему бы не перевести все триггера на передний фронт. хмм, как я понял используется именно спадающий фронт для корректного выключения/включения клока. Если делать все на восходящем фронте, то возможно укорочение периода клока, связанное с Tco + задержкой выключающего триггера. Не глитч конечно, но тем не менее. Цитата(SM @ Jan 19 2010, 14:19)  Лучше грамотно обконстрейнить недра через set_max_delay а разве констрейнов на клок не достаточно для данной схемы? интересуют именно асики, на форуме альтеры читал что ква старается в любом случае минимизировать длину трасс, поэтому большого смысла в задании таких задержек нет.
--------------------
|
|
|
|
|
Jan 20 2010, 18:03
|
Знающий
   
Группа: Свой
Сообщений: 654
Регистрация: 24-01-07
Из: Воронеж
Пользователь №: 24 737

|
Цитата(des00 @ Jan 20 2010, 06:42)  хмм, как я понял используется именно спадающий фронт для корректного выключения/включения клока. Если делать все на восходящем фронте, то возможно укорочение периода клока, связанное с Tco + задержкой выключающего триггера. Не глитч конечно, но тем не менее. Неее, задний фронт используется тогда когда клок с энейблом смешиваются по И, если мешать по ИЛИ нужно использовать передний фронт. В этих случаях tco триггера может быть от 0 до половины периода и это не будет влиять на выходной клок. А что касается lcell мысль такая: например имеем переключатель 2-х клоков - (c0 & e0) | (c1 & e1) и все это попадает в ЛУТ. причем оба клока всегда молотят. Могут ли возникнуть глитчи или нет точно не знаю. Если разделить на разные луты, то при ЛУТ = (c0 & e0) глитчи точно не возникнут.
|
|
|
|
|
Jan 20 2010, 18:28
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(des00 @ Jan 20 2010, 06:42)  а разве констрейнов на клок не достаточно для данной схемы? нет конечно, недостаточно. Сам мультиплексор оказывается необконстрейненным из-за асинхронности клоков. Поэтому надо конкретно прописать максимально допустимые задержки, чтобы потом в STA проверить, выполняются ли они, и не сотворил ли плейсер-роутер всяких чудес, что типа как енейбл идет до мультиплексора дольше чем период клока  Т.е. сам клок гарантировано будет подан правильно, так как входы мультиплексора это ендпойнты дерева, а вот энейблы - вопрос отдельный.
|
|
|
|
|
Jan 21 2010, 04:56
|
Вечный ламер
     
Группа: Модераторы
Сообщений: 7 248
Регистрация: 18-03-05
Из: Томск
Пользователь №: 3 453

|
Цитата(dvladim @ Jan 20 2010, 12:03)  А что касается lcell мысль такая: например имеем переключатель 2-х клоков - (c0 & e0) | (c1 & e1) и все это попадает в ЛУТ. причем оба клока всегда молотят. Могут ли возникнуть глитчи или нет точно не знаю. Если разделить на разные луты, то при ЛУТ = (c0 & e0) глитчи точно не возникнут. хмм, но ведь мультиплексор сначала выключает оба клока и только потом включает один из них. По идее глитч возникнуть не может %) Цитата(SM @ Jan 20 2010, 12:28)  Т.е. сам клок гарантировано будет подан правильно, так как входы мультиплексора это ендпойнты дерева, а вот энейблы - вопрос отдельный. Понял спасибо %)
--------------------
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|