реклама на сайте
подробности

 
 
> Безглитчевый мультиплексор клоков, Как правильно описывать, когда клоков больше чем 2
des00
сообщение Jan 18 2010, 16:54
Сообщение #1


Вечный ламер
******

Группа: Модераторы
Сообщений: 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);

Мне кажеться что оба варианта должны быть работоспособны, но может быть я ошибаюсь. Подскажите какой вариант является более правильным?
ЗЫ. Вариант использовать альтеровскую корку не предлагать, она не может покрыть всех вариантов используемых клоков %)


--------------------
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
SM
сообщение Jan 18 2010, 17:06
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Более правильный вариант вообще третий, до четырех клоков расширяется по аналогии smile.gif

Код
reg [1:0] clock_selector;
reg [1:0] loclk_dly;
reg [1:0] hiclk_dly;
reg [1:0] intclk_dly;

wire outclk;

always @(negedge lo_clk or posedge hw_reset)
  if (hw_reset) loclk_dly <= 2'b00; else
    loclk_dly <= {loclk_dly[0], (clock_selector == CK_LOW) && !hiclk_dly[1] && !intclk_dly[1] };

always @(negedge hi_clk or posedge hw_reset)
  if (hw_reset) hiclk_dly <= 2'b00; else
    hiclk_dly <= {hiclk_dly[0], (clock_selector == CK_HIGH) && !loclk_dly[1] && !intclk_dly[1] };

always @(negedge int_clk or posedge hw_reset)
  if (hw_reset) intclk_dly <= 2'b11; else
    intclk_dly <= {intclk_dly[0], ((clock_selector != CK_LOW) && (clock_selector != CK_HIGH)) && !hiclk_dly[1] && !loclk_dly[1] };

  wire tclk=(lo_clk & loclk_dly[1]) | (hi_clk & hiclk_dly[1]) | (int_clk & intclk_dly[1]);
  global gbl1 (.in(tclk), .out(outclk));
Go to the top of the page
 
+Quote Post
des00
сообщение Jan 18 2010, 17:16
Сообщение #3


Вечный ламер
******

Группа: Модераторы
Сообщений: 7 248
Регистрация: 18-03-05
Из: Томск
Пользователь №: 3 453



Цитата(SM @ Jan 18 2010, 11:06) *
Более правильный вариант вообще четвертый, до четырех клоков расширяется по аналогии smile.gif

спасибо, если я правильно понял в моем варианте нет асинхронных сбросов, как у вас и вы по сбросу ставите мультиплексор в определенное положение?


Цитата(des333 @ Jan 18 2010, 11:09) *
А тот, который Альтера предлашает, чем не годится? smile.gif

этот вариант эквивалентен приведеном коду %)

у меня ква для сыклона 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


--------------------
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 06:08
Рейтинг@Mail.ru


Страница сгенерированна за 0.01432 секунд с 7
ELECTRONIX ©2004-2016